在sql server中按月份和日期获取数据
问题描述:
我有一个带有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
答
使用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_NUMBER
与RANK
或DENSE_RANK
,按要求。
答
; 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及更高版本。
- 首先在CTE一个你发现你的分区列(YearMonth)
- 那么B中分配每条记录都有一个ROWNUM(这是可以改变的基础上您的订购citeria)
- ,然后你会得到最终的结果。
答
感谢您的回复。我做了一些改变,并在这里得到了解决方案。
; 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-11 10:06:56
是的,上午10点前回复了这个:)。现在我看到你想要每天的第一个结果。如果你转换为Varchar(10),你会得到一整天(没有时间),你很好去。 – Daniel 2013-02-11 16:39:51