2013-02-11 4 views
0

У меня есть таблица Задача с создан столбцом createdDate. Мне нужно получить все задачи, созданные за определенный месяц, и каждый день должен иметь не более 4 записей. Если в конкретную дату имеется более 4 записей, мы можем получить только первые 4 записи, которые сначала разбиваются на ящики. Существует еще один столбец CreatedTime.Извлечь данные по месяцам и дням в sql-сервере

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() в подзапроса или общей таблице Expression (КТР). Версия подзапроса:

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, как требуется.

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. Первый в КТР А вы нашли секционирования столбец (годМесяц),
  2. затем в B вы назначаете RowNum для каждой записи (это может быть изменено на основе вашего заказа citeria)
  3. и тогда вы получите конечный результат.
+0

Спасибо вам за ответ. Я сделал некоторые изменения и получил решения здесь. –

+0

Да, ответила это до 10 утра :). Теперь я вижу, что вы хотели получить первые результаты за каждый день. Если вы перейдете на Varchar (10), вы получите полный день (без времени), и вам будет хорошо. – Daniel

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 
Смежные вопросы