我想要一个带有ID表参数的select语句。理想的行为是,如果表中没有元素,则获取所有值,但是如果表中有元素,则仅选择那些值与表的ID参数匹配的值。
我的$_.Value
子句如下:
where
但是,结果始终会带回所有位置,即使LocationIds表包含一个值并且该ID仅匹配一个值。
我可以设置诸如的值,但它仍会带回所有位置:
SELECT * FROM BLAH
WHERE [TransactionDateTime] BETWEEN @BeginTransDate AND @EndTransDate AND
((SELECT COUNT(ID) FROM @LocationIds) = 0) OR (EXISTS (SELECT 1 FROM
@LocationIds WHERE t.LocationId = ID))
答案 0 :(得分:2)
我个人将这作为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)
答案 1 :(得分:1)
尝试一下:
SELECT *
FROM BLAH
WHERE [TransactionDateTime] BETWEEN @BeginTransDate AND @EndTransDate
AND (
(SELECT COUNT(ID) FROM @LocationIds) = 0
OR
ID in (SELECT ID FROM @LocationIds)
)
答案 2 :(得分:1)
您缺少一对方括号。
WHERE [TransactionDateTime] BETWEEN @BeginTransDate AND @EndTransDate AND
( ((SELECT COUNT(ID) FROM @LocationIds) = 0) OR (EXISTS (SELECT 1 FROM
@LocationIds WHERE t.LocationId = ID)) )
LEFT JOIN
可能是一个更简单的解决方案。
SELECT b.*
FROM BLAH b
LEFT JOIN @LocationIds l ON l.ID = b.LocationId