【问题标题】:Use IN operator in THEN Statement in SQL在 SQL 的 THEN 语句中使用 IN 运算符
【发布时间】:2019-10-28 05:58:12
【问题描述】:

我正在编写一个 SQL 语句,它将根据存储过程中给出的输入从表值参数中获取信息。如果输入值行计数大于零,则该条件应该有效。请指导我使用以下查询。

DECLARE @DivisionIds [dbo].[IDList]
DECLARE @StateIds [dbo].[IDList]

INSERT INTO @DivisionIds Values (1)
INSERT INTO @DivisionIds Values (1)
INSERT INTO @StateIds Values (1)
INSERT INTO @StateIds Values (3)
INSERT INTO @StateIds Values (31)
INSERT INTO @StateIds Values (43)

SET @DivsionRowCount = (SELECT COUNT(ID) FROM @DivisionIds)
SET @StateRowCount = (SELECT COUNT(ID) FROM @StateIds)

SELECT * FROM MedInv inv INNER JOIN Location loc ON inv.MedInvID = loc.MedInvID 
WHERE CustomerID = 210
AND
    @DivsionRowCount > 0 AND loc.DivisionID IN (SELECT ID FROM @DivisionIds)
AND
    @StateRowCount > 0 AND loc.StateID IN (SELECT ID FROM @StateIds)

如果我为@DivisionIds 和@StateIds 提供值,上面的代码可以正常工作。在某些情况下,@DivisionIds 和 StateIds 没有任何值。所以行数将为零。只有当行数大于零时,我才想运行上述条件。该怎么做?

我的实际代码包含其他条件的 CASE 语句,我想在 CASE 语句中包含上述条件,我尝试了以下方法但出现错误。

DECLARE @DivisionIds [dbo].[IDList]
DECLARE @StateIds [dbo].[IDList]

SET @DivsionRowCount = (SELECT COUNT(ID) FROM @DivisionIds)
SET @StateRowCount = (SELECT COUNT(ID) FROM @StateIds)

SELECT CustomerName, InvEstValue, Status FROM MedInv inv
INNER JOIN Location loc ON loc.MedInvID = inv.MedInvID
INNER JOIN Division div ON div.DivisionID = loc.DivisionID
INNER JOIN State st ON st.StateID = loc.StateID
WHERE inv.CustomerID = 210
AND
inv.CustomerName Like
CASE WHEN @CustomerName = '' THEN '%%' ELSE '%' + @CustomerName + '%' END
AND
   inv.AssetDescription Like
   CASE WHEN @AssetDescription = '' THEN '%%' ELSE '%' + @AssetDescription + '%' END
AND
    @DivsionRowCount > 0 AND loc.DivisionID IN (SELECT ID FROM @DivisionIds)
AND
    @StateRowCount > 0 AND loc.StateID IN (SELECT ID FROM @StateIds)
AND
    loc.DivisionID = 
    CASE WHEN (@DivsionRowCount > 0) THEN loc.DivisionID IN (SELECT ID FROM @DivisionIds) ELSE loc.DivisionID END

从上面,我在 INELSE 关键字附近遇到错误,说 IN 附近的语法不正确,ELSE 附近的语法不正确。期待ENDTHEN

请指导我如何在THEN 语句中使用IN 运算符。

我希望条件只有在输入值参数计数大于零时才会运行。

【问题讨论】:

  • 您收到错误是因为您尝试像不正确的子查询一样获取 loc.DivisionID
  • 您不能将 case 用作流控制。这是一个返回单个值的表达式。
  • 我该如何实现这个?

标签: sql-server


【解决方案1】:

我不确定您在您的情况下是否采取了正确的方法,但是 问题是你的最后一个条件是:

loc.DivisionID = in(...)

而“= in”的语法不正确

也许你可以直接在join中添加你的条件

INNER JOIN Division div ON loc.DivisionID IN (SELECT ID FROM @DivisionIds)

这是你所期望的吗? 但我认为您还需要将这两个条件放在联接中

AND
    @DivsionRowCount > 0 AND loc.DivisionID IN (SELECT ID FROM @DivisionIds)
AND
    @StateRowCount > 0 AND loc.StateID IN (SELECT ID FROM @StateIds)

【讨论】:

  • 感谢 Carbon 提供了解决方案。 INNER JOIN 符合我的要求。
【解决方案2】:

我会这样写:

DECLARE @DivisionIds [dbo].[IDList]
DECLARE @StateIds [dbo].[IDList]

SET @DivsionRowCount = (SELECT COUNT(ID) FROM @DivisionIds)
SET @StateRowCount = (SELECT COUNT(ID) FROM @StateIds)

SELECT CustomerName, InvEstValue, Status 
FROM MedInv inv
INNER JOIN Location loc 
    ON loc.MedInvID = inv.MedInvID
INNER JOIN Division div 
    ON div.DivisionID = loc.DivisionID
INNER JOIN State st 
    ON st.StateID = loc.StateID
WHERE inv.CustomerID = 210
AND (@CustomerName = '' OR inv.CustomerName Like '%' + @CustomerName + '%')
AND (@AssetDescription = '' OR inv.AssetDescription LIKE '%' + @AssetDescription + '%')

AND (@DivsionRowCount = 0 OR loc.DivisionID IN (SELECT ID FROM @DivisionIds))
AND (@StateRowCount = 0 OR loc.StateID IN (SELECT ID FROM @StateIds))

如果遇到性能问题,您可能需要添加选项(重新编译)。 查看revisiting catch-all queries on SQL in the wild blog 了解详情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-29
    • 1970-01-01
    相关资源
    最近更新 更多