的時候可以說我有一個包含許多類似的許多行的表:TSQL選擇最小和最大的行分組
ID Range Range_begining Profit
----------------------------------------------------
1 (100-150) 100 -20
2 (200-250) 200 40.2
3 (100-150) 100 100
4 (450-500) 450 -90
...
我做這樣一個簡單的查詢:
SELECT max([Range]) AS 'Range'
, count(ID) AS 'Count'
, round(avg([Profit]), 2) AS 'AVG Profit'
FROM
Orders
GROUP BY
Range_begining
在此之後運行查詢時,我得到的結果是這樣的:
Range Count AVG Profit
------------------------------------
(100-150) 2 40
(200-250) 1 40.2
(450-500) 1 -90
...
很簡單:)
我現在需要做的是用最小的和最大的利潤,其中數是選擇行大於10(這是一個參數)
我能得到最小值與此:
SELECT TOP 1 [Range], [AVG Profit] FROM (
SELECT max([Range]) AS 'Range'
, count(ID) AS 'Count'
, round(avg([Profit]), 2) AS 'AVG Profit'
FROM
Orders
GROUP BY
Range_begining) X
WHERE
[Count]>10
ORDER BY
[AVG Profit] ASC --or DESC if I want max profit
我正在考慮使用ORDER BY DESC爲上述查詢做一個UNION
,但這不是最好的解決方案。
我需要做的事情:
選擇2行:一個最小值,一個最大AVG利用Range進行分組時獲利。
編輯: 如果我加2移動列到我的主數據表是這樣的:
ID Range Range_begining Profit OrderDate Company
---------------------------------------------------------------------------------
1 (100-150) 100 -20 2012-01-02 1
2 (200-250) 200 40.2 2012-03-22 0
3 (100-150) 100 100 2012-02-05 0
4 (450-500) 450 -90 2012-05-12 1
...
,然後嘗試添加2個條件是這樣的:
; with ordering as (
SELECT max([Range]) AS 'Range'
, count(ID) AS 'Count'
, round(avg([Profit]), 2) AS 'AVG Profit'
, row_number() over (order by avg([Profit])) rn_min
, row_number() over (order by avg([Profit]) desc) rn_max
FROM
Orders
GROUP BY
Range_begining
HAVING COUNT(ID) > 10
AND [Company][email protected]
AND (@from= '' OR [OrderDate]>[email protected])
AND (@to= '' OR [OrderDate]<[email protected])
)
select [range], [count], [avg profit]
from ordering
where (rn_max = 1 or rn_min = 1)
我得到一個錯誤,因爲[公司]和[OrderDate]
在HAVING子句中無效,因爲它不包含在 集合函數或GROUP BY子句中。
我該如何解決這個問題?
EDIT2 明白了!
; with ordering as (
SELECT max([Range]) AS 'Range'
, count(ID) AS 'Count'
, round(avg([Profit]), 2) AS 'AVG Profit'
, row_number() over (order by avg([Profit])) rn_min
, row_number() over (order by avg([Profit]) desc) rn_max
FROM
Orders
WHERE
[Company][email protected]
AND (@from= '' OR [OrderDate]>[email protected])
AND (@to= '' OR [OrderDate]<[email protected])
GROUP BY
Range_begining
HAVING COUNT(ID) > 10
)
select [range], [count], [avg profit]
from ordering
where (rn_max = 1 or rn_min = 1)
編輯3 我可以用描述返回另一列是這樣的:
Range AVG Profit Description
-------------------------------------------------
(200-250) 40.2 Max profit here
(450-500) -90 Min profit, well done
EDIT 4 快速的答案(基於@NikolaMarkovinović答案):
; with ordering as (
SELECT max([Range]) AS 'Range'
, count(ID) AS 'Count'
, round(avg([Profit]), 2) AS 'AVG Profit'
, row_number() over (order by avg([Profit])) rn_min
, row_number() over (order by avg([Profit]) desc) rn_max
FROM
Orders
WHERE
[Company][email protected]
AND (@from= '' OR [OrderDate]>[email protected])
AND (@to= '' OR [OrderDate]<[email protected])
GROUP BY
Range_begining
HAVING COUNT(ID) > 10
)
SELECT
CASE WHEN rn_max=1 THEN 'This is max' ELSE 'Min' END AS 'Description'
,[range]
,[count]
,[avg profit]
FROM ordering
WHERE (rn_max = 1 or rn_min = 1)
請務必在您的問題中添加'SQL'標籤以獲得更多關注。 – 2012-08-17 08:20:12