Выберите запрос с диапазоном дат и одной датой в 2 отдельных столбцах

#sql #sql-server

#sql #sql-сервер

Вопрос:

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

Результат должен быть похож:

 Locations     |  Today's Count |  Mth to Date

 Site 1       |       72       |     475
 Site 2       |       61       |     341
 Site 3       |       10       |     179
  

До сих пор я пытался:

 SELECT 
    A.SITENAME, 
    COUNT(A.SALEID) AS 'TODAY'S COUNT',
    COUNT(M.SALEID) AS 'MTH to DATE'
FROM SALESDATA AS A 
LEFT JOIN SALESDATA as M on 
    M.SALEID = A.SALEID AND 
    M.SALEID BETWEEN DATEADD(DAY, -(DAY(GETDATE())), GETDATE()) AND
    DATEADD(dd, - 1, GETDATE())
WHERE (DATEADD(day, DATEDIFF(day, 0, A.SALEDATE), 0) >= DATEADD(dd, - 1, GETDATE()))
GROUP BY A.SITENAME
  

также:

 SELECT 
    A.SITENAME, 
    COUNT(D.SALEID) AS 'TODAY'S COUNT',
   COUNT(M.SALEID) AS 'MTH to DATE'
FROM SALESDATA AS A 
LEFT JOIN SALESDATA as M on 
    M.SALEID = A.SALEID AND 
    M.SALEID BETWEEN DATEADD(DAY, -(DAY(GETDATE())), GETDATE()) AND
    DATEADD(dd, - 1, GETDATE())
LEFT JOIN SALESDATA as D on 
    D.SALEID = A.SALEID AND
    D.SALEID AND
    (DATEADD(day, DATEDIFF(day, 0, A.SALEDATE), 0) >= DATEADD(dd, - 1, GETDATE()))
GROUP BY A.SITENAME
  

Я получаю это:

 Locations     |  Today's Count |  Mth to Date

 Site 1       |       72       |     0
 Site 2       |       61       |     0
 Site 3       |       10       |     0
  

Также пробовал использовать CASE , но я действительно понятия не имел.

Любая помощь была бы весьма признательна.

Комментарии:

1. пример данных был бы хорош

2. Вы уверены , что этот код работает? COUNT(A.SALEID) AS 'TODAY'S COUNT', это приведет к ошибке ( Incorrect syntax near 's'. ), поэтому вы не получите никаких результатов. Как правило, лучше избегать имен (объектов и псевдонимов), которые требуют идентификации с разделителями, и использовать уровень представления, чтобы сделать их более «многословными». и также предпочтительно не использовать одинарные кавычки ( ' ) для их разграничения, поскольку одинарные кавычки используются для буквенных строк. Используйте скобки ( [] ) в T-SQL или двойные кавычки ( " ), если вы уверены, что QUOTED_IDENTIFIER всегда установлено значение ON .

Ответ №1:

Я предлагаю использовать здесь оконные функции — в конце концов, вы можете использовать их в подзапросе и агрегировать их по желанию. С помощью этого вы можете рассчитать общее количество за месяц, а также плавающее значение, где вы видите влияние количества дней на месячную сумму.

Вот пример:

 CREATE TABLE TestData (
  MySite NVARCHAR(10)
  ,MyDate date
  ,MyVal int
 )
GO

INSERT INTO TestData VALUES
('Site 1', '2020-08-01', 1)
,('Site 1', '2020-08-02', 1)
,('Site 1', '2020-08-03', 1)
,('Site 1', '2020-09-01', 1)
,('Site 1', '2020-09-02', 1)
,('Site 1', '2020-09-03', 1)
,('Site 1', '2020-09-04', 1)
,('Site 2', '2020-08-03', 1)
,('Site 2', '2020-09-01', 1)
,('Site 2', '2020-09-02', 1)
GO

SELECT MySite
      ,MyDate
      ,COUNT(MyVal) OVER (PARTITION BY MySite, MyDate) CntToday
      ,COUNT(MyVal) OVER (PARTITION BY MySite, YEAR(MyDate)*100 MONTH(MyDate)) CntMonthTotal
      ,COUNT(MyVal) OVER (PARTITION BY MySite, YEAR(MyDate)*100 MONTH(MyDate) ORDER BY MyDate ROWS UNBOUNDED PRECEDING) CntMonthFloating
  FROM TestData
  

Подробности см. в fiddle:http://sqlfiddle.com /#!18/82827/9/1

Ответ №2:

 select
sitename
,count(case when saledate = convert(date,getdate()) then distinct saleId end) sales_today
,count(case when month(SALEDATE) = 09 and year(SALEDATE) = 2020 then distinct saleId end) sales_month
from SALESDATA 
group by
sitename
  

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

Также вы, где предложение включает только сегодняшние и вчерашние данные о продажах, как вы сделали сегодня и сегодня — 1 дата, поэтому вы никогда не получите данные за месяцы.

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

Ответ №3:

Используйте условную агрегацию:

 SELECT s.SITENAME,
       SUM(CASE WHEN s.saledate >= CONVERT(date, GETDATE()) THEN 1 ELSE 0 END) as todays_cnt,
       COUNT(*) as month_to_date 
FROM SALESDATA s
WHERE saledate >= DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1)
GROUP BY s.SITENAME