#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