Лично я делаю это как 2 запроса, как план запроса для случаев, когда в @LocationIds
есть строки, и они, вероятно, будут достаточно различаться, чтобы повторное использование плана не было выгодно для другого, поэтому вы получаете:
IF (SELECT COUNT(*) FROM @LocationIds) = 0 BEGIN
SELECT *
FROM BLAH
WHERE [TransactionDateTime] BETWEEN @BeginTransDate AND @EndTransDate;
END ELSE BEGIN
SELECT *
FROM BLAH B
WHERE [TransactionDateTime] BETWEEN @BeginTransDate AND @EndTransDate
AND EXISTS (SELECT 1
FROM @LocationIds L
WHERE B.LocationID = L.ID);
END
В качестве альтернативы вы можете использовать динамический SQL для построения запроса в зависимости от того, нужны ли значения @LociationIDs
:
DECLARE @SQL nvarchar(MAX);
SET @SQL = N'SELECT *' + NCHAR(13) + NCHAR(10) +
N'FROM BLAH B' + NCHAR(13) + NCHAR(10) +
N'WHERE [TransactionDateTime] BETWEEN @BeginTransDate AND @EndTransDate' +
CASE WHEN (SELECT COUNT(*) FROM @LocationIds) = 0 THEN ';'
ELSE NCHAR(13) + NCHAR(10) +
N' AND EXISTS (SELECT 1' + NCHAR(13) + NCHAR(10) +
N' FROM @LocationIds L' + NCHAR(13) + NCHAR(10) +
N' WHERE B.LocationID = L.ID);'
END;
EXEC sp_executesql @SQL, N'@BeginTransDate date, @EndTransDate date', @BeginTransDate = @BeginTransDate, @EndTransDate = @EndTransDate;
Примечание. Я догадался, что @BeginTransDate
и @EndTransDate
являются date
, а не datetime
.Если они являются последними, то этот запрос вряд ли будет работать так, как вы хотите, в любом случае, и вам лучше использовать следующую логику:
WHERE TransactionDateTime >= @BeginTransDate
AND TransactionDateTime < DATEADD(DAY, 1, @EndTransDate)