2016-09-07 2 views
0

Я пишу SQL-запрос, который извлекает некоторую информацию за последние 4 недели. Я вижу две проблемы с моими результатами (см. Ниже).Даты заказа на 4 недели

Первая проблема заключается в том, что, когда я оглядываюсь назад на четыре недели, диапазон должен быть 10 августа - 6 сентября. Когда я заказываю «День месяца», даты в сентябре будут перенесены в верхнюю часть результатов когда они действительно должны быть в конце. Поэтому мои результаты должны начинаться с 10 (август) и заканчиваться в 6 (сентябрь).

Вторая проблема Я пропустил несколько случайных дат (3, 4, 13, 27).

Day of the Month Number of X 
1     125 
2     77 
5     5 
6     23 
10     145 
11     177 
12     116 
14     2 
15     199 
16     154 
17     134 
18     140 
19     154 
21     8 
22     166 
23     145 
24     151 
25     107 
26     79 
28     3 
29     151 
30     163 
31     147 

Вот общая версия моего запроса:

DECLARE @startDate datetime, @endDate datetime; 
SET @startDate = dateadd(day, -28, GETDATE()); 
SET @endDate = dateadd(day, -1, GETDATE()); 

Select DATEPArt(dd, Time) AS 'Day of the Month', count(*) AS ' Number of X' 
from SomeTable ST 
where Time >= @startDate 
AND Time < @endDate 
group by DATEPArt(dd, Time) 
order by 'Day of the Month' 
+1

Если вам не хватает данных о дате, возможно, вам придется создать и использовать таблицу календаря. –

ответ

1

Для первой задачи вы можете заказать по дате, чтобы получить правильный порядок даты. Я использую convert, чтобы получить бесплатную дату, чтобы группа записей правильно.

DECLARE @StartDate datetime, @EndDate datetime; 
SET @StartDate = DATEADD(day, -28, GETDATE()); 
SET @EndDate = DATEADD(day, -1, GETDATE()); 

SELECT 
DATEPART(dd, Convert(date, Time)) AS 'Day of the Month', COUNT(*) AS ' Number of X' 
FROM SomeTable ST 
WHERE Time >= @StartDate 
AND Time < @EndDate 
GROUP BY Convert(date, Time) 
ORDER BY Convert(date, Time) 

Что касается недостающих дней, это сложнее, поскольку данные должны быть там, где группа может работать.

Один из вариантов - создать временную таблицу со всеми датами, а затем присоединиться к данным. Это все равно оставит строку, в которой соединение не найдет никаких данных и может получить счет «нуля».

DECLARE @StartDate datetime, @EndDate datetime; 
SET @StartDate = DATEADD(day, -28, GETDATE()); 
SET @EndDate = DATEADD(day, -1, GETDATE()); 

--Create temporary table with all days between the two dates 
;WITH d(d) AS 
(
    SELECT DATEADD(DAY, n, DATEADD(DAY, DATEDIFF(DAY, 0, @StartDate), 0)) 
    FROM (SELECT TOP (DATEDIFF(DAY, @StartDate, @EndDate) + 1) 
    n = ROW_NUMBER() OVER (ORDER BY [object_id]) - 1 
    FROM sys.all_objects ORDER BY [object_id]) AS n 
) 
--Join in our query to the table temporary table 
SELECT 
    DATEPART(dd, d.d) AS 'Day of the Month', 
    COUNT(Time) AS ' Number of X' 
FROM d LEFT OUTER JOIN SomeTable ST ON DATEPART(dd, d.d) = DATEPART(dd, Time) 
           AND Time >= @StartDate 
           AND Time < @EndDate 
GROUP BY d.d 
ORDER BY d.d 
+0

Заказ этого способа отлично работает в ms-sql, хотя может не работать в других формах sql. Я изменил порядок, чтобы вместо этого использовать индекс столбца. –

+0

Спасибо, Джеймс, к сожалению, все, что делает, это добавить столбец, который показывает месяц. Даты сентября остаются на вершине. – muhqa

+0

Я не могу воспроизвести, если запрос выполняется, результаты упорядочиваются по месяцам и месяцам месяца. Хотя я заметил, что я не изменил запрос до того, как он у вас есть. Не могли бы вы скопировать второй запрос и повторить попытку? –

Смежные вопросы