2013-02-11 78 views
0

我有一個帶有createdDate列的任務表。我需要獲得在特定月份創建的所有任務,每天不應該有超過4條記錄。如果在特定日期有超過4條記錄,那麼我們只能得到第一條第一條記錄。還有另一列CreatedTime。在sql server中按月份和日期獲取數據

Task 
(
    id 
    ,CreatedDate 
    ,CreatedTime 

) 

結果應該是

id  CreatedDate 

1  1/1/2013 
2  1/1/2013 
3  1/1/2013 
4  1/1/2013 
5  1/2/2013 
6  1/2/2013 
7  1/2/2013 
8  1/2/2013 

回答

0

使用ROW_NUMBER()在子查詢或公用表表達式(CTE)。子查詢的版本:

SELECT 
    * --TODO: Columns 
FROM 
    (SELECT 
     *,ROW_NUMBER() OVER (PARTITION BY CreatedDate ORDER BY CreatedTime) as rn 
    FROM 
     Task 
    ) t 
WHERE 
    rn between 1 and 4 

如果(在同一天的兩行具有相同CreatedTime)曾在你的數據可能的聯繫,你需要把這些轉化爲顯性的考慮,你可以換ROW_NUMBERRANKDENSE_RANK,按要求。

0
; WITH A AS (
SELECT ID, CreatedDate 
, convert(VARCHAR(7), CreatedDate, 121) AS YearMonth --will return something like 2012-01 
FROM Task 
), 
B AS (
SELECT ID, CreatedDate 
, ROW_NUMBER() OVER (PARTITION BY YearMonth ORDER BY CreatedDate, ID) AS RowNum 
FROM A) 
SELECT ID, CreatedDate 
FROM B 
WHERE RowNum<=4 
ORDER BY ID 

這適用於SQL 2005及更高版本。

  1. 首先在CTE一個你發現你的分區列(YearMonth)
  2. 那麼B中分配每條記錄都有一個ROWNUM(這是可以改變的基礎上您的訂購citeria)
  3. ,然後你會得到最終的結果。
+0

感謝您的回覆。我做了一些改變,並在這裏得到了解決方案。 – 2013-02-11 10:06:56

+0

是的,上午10點前回復了這個:)。現在我看到你想要每天的第一個結果。如果你轉換爲Varchar(10),你會得到一整天(沒有時間),你很好去。 – Daniel 2013-02-11 16:39:51

0

感謝您的回覆。我做了一些改變,並在這裏得到了解決方案。

; WITH A 
AS 
(
SELECT ID, CreatedDate , DAY(CreatedDate) AS Day 
FROM Task 
WHERE CreatedDate BETWEEN '01/01/2013 00:00:00' AND '01/31/2013 23:59:59' 
) 
, 
B AS 
(
    SELECT 
    ROW_NUMBER() OVER (PARTITION BY Day ORDER BY CreatedDate, ID) AS RowNum 
    ,* 
    FROM A 
) 


select 
DAY(CreatedDate) as Day1 
, MONTH(CreatedDate) as Month 
, YEAR(dueDate) as Year 
, * 
from B 
WHERE RowNum <= 4 
order by Year,Month,Day1, CreatedDate 
相關問題