sql - 想从表中选择,但它忽略了它
问题描述
我想要一个带有 ID 表参数的 select 语句。期望的行为是,如果表中没有元素,则获取所有值,但如果表中有元素,则仅选择那些值与表的 ID 参数匹配的值。
我的where
条款如下所示:
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))
但是,结果总是带回所有位置,即使 LocationIds 表包含一个值并且该 ID 仅匹配一个值。
我可以设置值,但它仍然会带回所有位置:
DECLARE @LocationIds TABLE
(
ID int
)
INSERT INTO @LocationIds (ID)
VALUES (10227)
解决方案
就个人而言,我将其作为 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
and@EndTransDate
是 a date
,而不是 a datetime
。如果它们是后者,那么该查询无论如何都不太可能按您的意愿工作,您最好使用以下逻辑:
WHERE TransactionDateTime >= @BeginTransDate
AND TransactionDateTime < DATEADD(DAY, 1, @EndTransDate)
推荐阅读
- python - 具有动态输入形状的 CNN
- c# - 如何在 Linq、windows 窗体中调用计算年龄和调用方法
- excel - 替代 application.calculation = xlcalculationmanual 以加快 mailmerge vba 代码?
- powershell - 在管道对象上调用方法
- python - 烧瓶 sqlite3 安全问题
- python - 根据条件更新 Numpy 数组
- dynamic - 如何从目录中获取文件列表?
- materialize - 如何在物化中使用 vanilla java-script 初始化轮播全角和指标?
- django - Django Admin中删除操作的奇怪错误
- angular7 - 会话过期时重定向到登录页面