вернуть результат, даже если нет данных за этот день / неделю / месяц - PullRequest
0 голосов
/ 02 ноября 2018

У меня есть база данных MSSQL, и я хочу получить значение для каждого дня / недели / месяца в отдельных запросах.

У меня это работает просто отлично, за исключением интервалов, когда нет данных, они ничего не возвращают. И поскольку я помещаю это в график, я хочу, чтобы он отображал как минимум 0 или NULL, вместо того, чтобы прыгать дни или недели и т. Д.

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

select CAST(Placements.CreatedOn AS DATE) AS 
date,SUM(Placements.CommissionPerc * (Placements.PlacementFee / 100)) AS value 
from [placements] 
where [Placements].[CreatedOn] >= '2018-06-07' and [Placements].[CreatedOn] < '2018-06-12' 
group by CAST(Placements.CreatedOn AS DATE) 
order by CAST(Placements.CreatedOn AS DATE) ASC

Это возвращает результат как:

result

Таким образом, он возвращает 0, когда данные на самом деле равны 0, но когда их нет, ничего не получается для дней 9, 10 и 12

Как я могу это исправить? спасибо

Ответы [ 2 ]

0 голосов
/ 02 ноября 2018

Лучше всего использовать постоянную календарную таблицу, но вот пример, который использует CTE для создания дат, необходимых для LEFT JOIN. Это использует максимум 1000 дней, но может быть продлено по мере необходимости.

DECLARE 
      @StartDate date = '2018-06-07'
    , @EndDate date = '2018-06-12';
WITH 
     t10 AS (SELECT n FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) t(n))
    ,t1k AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) - 1 AS num  FROM t10 AS a CROSS JOIN t10 AS b CROSS JOIN t10 AS c)
    ,calendar AS (SELECT DATEADD(day, num, @StartDate) AS calendar_date
        FROM t1k
        WHERE num <= DATEDIFF(day, @StartDate, @EndDate)
        )
SELECT
      calendar.calendar_date AS date
    , SUM( COALESCE(Placements.CommissionPerc * (Placements.PlacementFee / 100),0 ) ) AS value 
FROM calendar
LEFT JOIN [placements] ON [Placements].[CreatedOn] = calendar.calendar_date
GROUP BY calendar.calendar_date
ORDER BY calendar.calendar_date ASC;
0 голосов
/ 02 ноября 2018

Используя рекурсивный CTE, вы можете создать список дат.
Который затем можно использовать, чтобы присоединиться к вашему столу.

Пример:

WITH DATES2018 AS
(
  SELECT CAST('2018-01-01' AS DATE) AS [date]

  UNION ALL

  SELECT DATEADD(day, 1, [date])
  FROM DATES2018
  WHERE [date] < CAST('2018-12-31' AS DATE)
)
SELECT 
d.[Date],
SUM(p.CommissionPerc * (p.PlacementFee / 100.0)) AS [value] 
FROM DATES2018 AS d
LEFT JOIN [Placements] AS p ON CAST(p.CreatedOn AS DATE) = d.[Date]
WHERE d.[Date] BETWEEN '2018-06-07' AND '2018-06-11' 
GROUP BY d.[Date]
ORDER BY d.[Date] ASC
OPTION (MAXRECURSION 366)

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

Кстати, если переменные используются для даты начала и окончания, тогда этот SQL можно оптимизировать.

DECLARE @StartDate DATE = '2018-06-07';
DECLARE @EndDate DATE = '2018-06-11';

WITH DATES AS
(
  SELECT @StartDate AS [date]

  UNION ALL

  SELECT DATEADD(day, 1, [date])
  FROM DATES
  WHERE [date] < @EndDate
)
SELECT 
d.[Date],
SUM(p.CommissionPerc * (p.PlacementFee / 100.0)) AS [value] 
FROM DATES AS d
LEFT JOIN [Placements] AS p 
  ON p.CreatedOn BETWEEN CAST(@StartDate AS DATETIME) AND CAST(DATEADD(day, 1, @EndDate) AS DATETIME) AND
     CAST(p.CreatedOn AS DATE) = d.[Date]
GROUP BY d.[Date]
ORDER BY d.[Date] ASC
OPTION (MAXRECURSION 0)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...