2011-04-28 81 views
0

它返回按CountOfRecords DESC排序的所有行。我想在這裏只有七排,顯示特定日期的最高價值。所以一週中的每一天都應該只發生一次。這可能沒有很多痛苦嗎?SQL - 選擇一週中的每一天的最高記錄數

SELECT 
    Count(*) As CountOfRecords, 
    CAST(FLOOR(CAST([visit].[datetimeentered] AS float)) AS smalldatetime) AS DateEntered, 
    DatePart(dw, visit.datetimeentered) As DayOfTheWeek 
FROM visit 
INNER JOIN useragent ON useragent.useragentid = visit.useragentid 
WHERE useragent.isbot = 0 
GROUP BY CAST(FLOOR(CAST([visit].[datetimeentered] AS float)) AS smalldatetime), 
    DatePart(dw, visit.datetimeentered) 
ORDER BY CountOfRecords DESC 

EDIT1:
我覺得兩個答案都在同樣的事情得到。我已經接受了首先發布的那個。我也要提到它的工作原理,而另一個則沒有。我收到以下錯誤,當我運行marc_s的查詢:

Msg 207, Level 16, State 1, Line 29 
Invalid column name 'RowNum'. 
Msg 207, Level 16, State 1, Line 25 
Invalid column name 'CountOfRecords'. 
Msg 207, Level 16, State 1, Line 26 
Invalid column name 'DateEntered'. 
Msg 207, Level 16, State 1, Line 27 
Invalid column name 'DayOfTheWeek'. 

特別感謝marc_s您指出一個簡單的方法來獲得僅從日期時間的日期部分。

+1

你已經將數據分組在看起來是你問題的正確方法 - 是否有一個原因,你不能添加MAX(fieldname),其中fieldname是你想要的最高可用值的字段 - 到你的SELECT ? – 2011-04-28 20:11:26

+0

什麼數據庫產品和版本?它聞起來像SQL Server。如果是這樣,什麼版本? – Thomas 2011-04-28 20:21:30

+0

我沒有提到這是SQL Server 2008.我試過了你的建議,但它沒有奏效。 – HK1 2011-04-28 20:21:46

回答

1

根據您的查詢:

WITH groupedByDay AS (
    SELECT 
    Count(*) As CountOfRecords, 
    CAST(FLOOR(CAST([visit].[datetimeentered] AS float)) AS smalldatetime) AS DateEntered 
    FROM visit 
    INNER JOIN useragent ON useragent.useragentid = visit.useragentid 
    WHERE useragent.isbot = 0 
    GROUP BY CAST(FLOOR(CAST([visit].[datetimeentered] AS float)) AS smalldatetime) 
), 
ranked AS (
    SELECT 
    CountOfRecords, 
    DateEntered, 
    DOW = DATENAME(dw, DateEntered), 
    rank = ROW_NUMBER() OVER (PARTITION BY DatePart(dw, DateEntered) 
           ORDER BY CountOfRecords DESC) 
    FROM groupedByDay 
) 
SELECT 
    CountOfRecords, 
    DateEntered, 
    DOW 
FROM ranked 
WHERE rank = 1 
ORDER BY CountOfRecords DESC 

這將返回一行一週的每一天在表中表示。如果最大值中可能有CountOfRecords的重複項,並且您想要全部返回它們,請使用RANK()而不是ROW_NUMBER()

1

在SQL Server 2005和更新,你可以使用一個CTE(公共表表達式)與ROW_NUMBER()排名功能和PARTITION BY條款 - 這樣的事情:

;WITH DataByDayOfWeek AS 
(
    SELECT 
     Count(*) As CountOfRecords, 
     CAST(FLOOR(CAST(v.[datetimeentered] AS float)) AS smalldatetime) AS DateEntered, 
     DatePart(dw, v.datetimeentered) As DayOfTheWeek 
    FROM dbo.visit v 
    INNER JOIN dbo.useragent u ON u.useragentid = v.useragentid 
    WHERE u.isbot = 0 
    GROUP BY 
     CAST(FLOOR(CAST(v.[datetimeentered] AS float)) AS smalldatetime), 
     DatePart(dw, v.datetimeentered) 
), 
HighestValues AS 
(
    SELECT 
     CountOfRecords, 
     DateEntered, 
     DayOfTheWeek, 
     ROW_NUMBER() OVER(PARTITION BY DayOfTheWeek 
         ORDER BY CountOfRecords DESC) 'RowNum' 
    FROM DataByDayOfWeek 
) 
SELECT 
    CountOfRecords, 
    DateEntered, 
    DayOfTheWeek 
WHERE 
    RowNum = 1 

讓我解釋一下:

  • 第一個CTE確實計數了記錄,基本上 - 所以你會得到一個條目,每個DateEntered記錄數和星期幾
  • 第二個CTE基於在第一個CTE上,它將你的數據「分區」到DayOfTheWeek - 因此對於每週不同的一天,你會得到一個從1開始的計數器。一週中每一天的數據按記錄計數以降序排列,所以最高值具有RowNum爲1

所以選擇所有從第二CTE具有RowNum = 1給你一週的每一天最高值的行。

作爲一個方面說明:我相信,在SQL Server 2008中,你可以更輕鬆地將日期時間轉換爲嚴格DATE它不僅具有DATE - 沒時間 - 像這樣:

CAST(v.DateTimeEntered AS DATE) 

沒有更多的麻煩與轉換爲浮動,然後到smalldatetime - 試試吧!

相關問題