[英]SQL Aggregates OVER and PARTITION
所有,
這是我關於Stackoverflow的第一篇文章,所以輕松吧...
我正在使用SQL Server 2008。
我剛開始編寫SQL查詢,但遇到一個我認為很簡單的問題,但是我已經奮斗了2天。 我有一組看起來像這樣的數據:
UserId Duration(Seconds) Month
1 45 January
1 90 January
1 50 February
1 42 February
2 80 January
2 110 February
3 45 January
3 62 January
3 56 January
3 60 February
現在,我要編寫一個查詢,為我提供特定用戶的平均值,並將其與該月所有用戶的平均值進行比較。 因此,查詢用戶#1后的結果數據集將如下所示:
UserId Duration(seconds) OrganizationDuration(Seconds) Month
1 67.5 63 January
1 46 65.5 February
我一直在圍繞不同的子查詢和按場景分組,似乎沒有任何工作。 最近,我一直在嘗試OVER和PARTITION BY,但也沒有成功。 我最新的查詢如下所示:
select Userid,
AVG(duration) OVER () as OrgAverage,
AVG(duration) as UserAverage,
DATENAME(mm,MONTH(StartDate)) as Month
from table.name
where YEAR(StartDate)=2014
AND userid=119
GROUP BY MONTH(StartDate), UserId
該查詢在選擇列表中用“持續時間”轟炸,因為它沒有包含在聚合函數或GROUP BY子句中,因此無效。
請記住,我正在處理大量數據。 我認為我可以使其與CASE語句一起使用,但是我正在尋找一種更簡潔,更有效的方式來編寫查詢(如果可能)。
謝謝!
平均函數中缺少分區子句
OVER ( Partition by MONTH(StartDate))
您在這里將兩個查詢結合在一起:
如果您一次僅要返回一個用戶的數據,那么內聯選擇可能會給您帶來歡樂:
SELECT AVG(a.duration) AS UserAvergage,
(SELECT AVG(b.Duration) FROM tbl b WHERE MONTH(b.StartDate) = MONTH(a.StartDate)) AS OrgAverage
...
FROM tbl a
WHERE userid = 119
GROUP BY MONTH(StartDate), UserId
注意-在MONTH上使用比較可能會比較慢-使用CTE(通用表表達式)可能會更好
我能夠通過自我連接完成它,這可能是一種更好的方法。
Select UserId, AVG(t1.Duration) as Duration, t2.duration as OrgDur, t1.Month
from #temp t1
inner join (Select Distinct MONTH, AVG(Duration) over (partition by Month) as duration
from #temp) t2 on t2.Month = t1.Month
group by t1.Month, t1.UserId, t2.Duration
order by t1.UserId, Month desc
這里使用的CTE可能是更好的解決方案,而且絕對更易於閱讀
With MonthlyAverage
as
(
Select MONTH, AVG(Duration) as OrgDur
from #temp
group by Month
)
Select UserId, AVG(t1.Duration) as Duration, m.duration as OrgDur , t1.Month
from #temp t1
inner join MonthlyAverage m on m.Month = t1.Month
group by UserId, t1.Month, m.duration
Please try this. It works fine to me.
WITH C1
AS
(
SELECT
AVG(Duration) AS TotalAvg,
[Month]
FROM [dbo].[Test]
GROUP BY [Month]
),
C2
AS
(
SELECT Distinct UserID,
AVG(Duration) OVER(PARTITION BY UserID, [Month] ORDER BY UserID) AS DetailedAvg,
[Month]
FROM [dbo].[Test]
)
SELECT C2.*, C1.TotalAvg
FROM C2 c2
INNER JOIN C1 c1 ON c1.[Month] = c2.[Month]
ORDER BY c2.UserID, c2.[Month] desc;
您可以在下面用更少的代碼嘗試。
SELECT Distinct UserID,
AVG(Duration) OVER(PARTITION BY [Month]) AS TotalAvg,
AVG(Duration) OVER(PARTITION BY UserID, [Month] ORDER BY UserID) AS DetailedAvg,
[Month]
FROM [dbo].[Test]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.