0

私は、createdDate 列を持つテーブル Task を持っています。特定の月に作成されたすべてのタスクを取得する必要があり、毎日のレコードが 4 つを超えてはなりません。特定の日付に 4 つ以上のレコードがある場合、最初に作成された最初の 4 つのレコードのみを取得できます。別の列 CreatedTime があります。

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  
4

3 に答える 3

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 A で、パーティショニング列 (YearMonth) を見つけます。
  2. 次に、B で各レコードに RowNum を割り当てます (これは、順序基準に基づいて変更できます)。
  3. そして、最終結果が得られます。
于 2013-02-11T08:11:29.220 に答える
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同じ日に同じ行が 2 つある)、それらを明示的に考慮する必要がある場合は、必要に応じROW_NUMBERRANKまたはと交換できますDENSE_RANK

于 2013-02-11T08:03:55.667 に答える
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
于 2013-02-11T10:07:46.343 に答える