По сути, при запуске отчета я хотел бы отображать данные с начала года; пока не, это январь, значит, я хочу показать весь прошлый год.
Я пытался поместить это в свой оператор where, используя case или iif. В обоих случаях я получаю одну и ту же ошибку: Сообщение 102, уровень 15, состояние 1 ... Неверный синтаксис рядом с "между".
SELECT
name,
owner,
duedate,
submitteddate
FROM Table
WHERE submitteddate IS NOT NULL AND
CASE WHEN MONTH(GETDATE()) = 1
THEN submitteddate between DATEADD(YEAR, DATEDIFF(YEAR, '19000101', GETDATE()) - 1 , '19000101') AND DATEADD(d, -1, DATEADD(YEAR, DATEDIFF(YEAR, '19000101', GETDATE()), '19000101'))))
ELSE submitteddate between DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), 0) AND GETDATE()))
end
Похоже, это связано с использованием браслетов. попробуйте, как показано ниже:
SELECT
name,
owner,
duedate,
submitteddate
FROM Table
WHERE submitteddate IS NOT NULL AND
CASE WHEN MONTH(GETDATE()) = 1
THEN submitteddate between DATEADD(YEAR, DATEDIFF(YEAR, '19000101', GETDATE()) - 1 , '19000101') AND DATEADD(d, -1, DATEADD(YEAR, DATEDIFF(YEAR, '19000101', GETDATE()), '19000101'))
ELSE submitteddate between DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), 0) AND GETDATE()
end
Это не сработает; выражение CASE
не создает полного логического выражения. В предложении WHERE
вы не можете иметь CASE WHEN {expression} THEN {Boolean Expression} ELSE {Boolean Expression} END
и не следовать ему без логического оператора и дополнительного выражения. Как и любое другое предложение, оно должно быть в формате {CASE Expression} = {Expression}
(конечно, вы можете заменить =
на !=
, >
, <
, IN
или любой другой логический оператор)
....WHERE YEAR(submitteddate) = YEAR(GETDATE())
- CASE WHEN MONTH(GETDATE()) = 1 THEN 1 ELSE 0 END
Вместо использования выражения CASE
в WHERE
, которое не поддерживает SARG, вам будет гораздо лучше использовать переменные:
DECLARE @StartDate DATE, @EndDate Date;
SET @StartDate = CASE DATEPART(MONTH,GETDATE()) WHEN 1 THEN DATEADD(YEAR, DATEDIFF(YEAR, 0,GETDATE())-1,0)
ELSE DATEADD(YEAR, DATEDIFF(YEAR,0,GETDATE()),0)
END;
SET @EndDate = DATEADD(YEAR,DATEDIFF(YEAR, 0,@StartDate)+1,0);
--SELECT @StartDate, @EndDate; --Uncomment to check the values, but would break SSRS, as it only reads the first returned dataset.
SELECT [name],
[owner],
duedate,
submitteddate
FROM [Table]
WHERE submitteddate >= @StartDate
AND submitteddate < @EndDate;
Обратите внимание, что нет необходимости проверять, является ли значение submitteddate
NULL
или нет. NULL = {expression}
всегда будет приводить к «неизвестно», что неверно и, следовательно, не будет возвращено в наборе данных. Таким образом, если вам не нужны значения NULL
, тогда предложение IS NOT NULL
бессмысленно в WHERE
, например:
WHERE [Column] IS NOT NULL
AND [Column] = 1;
Вышеупомянутое вернет точно такие же строки, как:
WHERE [Column] = 1;
Как насчет
WHERE
submitteddate >=
IIF(MONTH(GETDATE()) = 1, DATEADD(Year, -1, GETDATE()), '1900-01-01')
AND submitteddate <= GETDATE();
Или используя переменную
DECLARE @FromDate DATEIME = (SELECT IIF(MONTH(GETDATE()) = 1, DATEADD(Year, -1, GETDATE()), '1900-01-01'));
SELECT *
FROM Table
WHERE
submitteddate >=
@FromDate
AND submitteddate <= GETDATE();
Ни то, ни другое не дало бы нужного результата в январе. Если, например, сегодня был 31.01.2019, диапазон будет от 01.01.2019 до 31.01.2019. Это данные за 13 месяцев, а не все за прошлый год.
@Larnu SELECT DATEADD(Year, -1,'2019-01-31')
дает 2018-01-31 00:00:00
не 2018-01-01, поэтому в том месте, где он будет между 2018-01-31 и 2019-01-31
submitteddate BETWEEN @FromDate AND GETDATE();
Если сегодня 20190131
, то GETDATE()
вернет 20190131
. OP указывает «Сейчас январь, значит, я хочу показать весь прошлый год»., а не «сейчас январь, тогда я хочу отобразить весь прошлый год до настоящего времени».
Как правило, лучше использовать конструкции AND / OR вместо выражений case в предложении WHERE.