【问题标题】:issues with the in statement using a subquery使用子查询的 in 语句问题
【发布时间】:2020-02-18 16:41:16
【问题描述】:

这个声明的问题

    select * from table 
        where ID in (case when table1.changes = 40 THEN 
        select top 1 STUFF((SELECT  ',' + CAST(ID as varchar) FROM Tabl1
                WHERE UserID = 121   FOR XML PATH('')), 1, 1, '') 
                    FROM Tabl1 where UserID = 121
else 
id
end
        )

使用上面,报错

消息 245,第 16 级,状态 1,第 3 行

将 nvarchar 值 '167,196,107,108,169,111,115,16,162' 转换为数据类型 int 时转换失败。

【问题讨论】:

  • 为什么要将整数 ID 转换为分隔字符串?您在这里不需要STUFF( ... FOR XML),您可以轻松地加入 ID 列并在 UserID 上过滤您的第二个表。请参阅我对简化查询的回答。
  • 从答案中的 cmets 来看,我们似乎实际上在这里有一个 XY Problem,或者 OP 只给了我们真正问题的一小部分。他们现在正在引用 CASE 不起作用,但是,他们的问题中没有这样的表达。
  • 您的问题被否决了,因为您正在回答未在问题中发布的要求的答案。请更新您的问题,向我们展示您实际尝试做的事情以及您认为需要使用CASE 声明的原因。
  • CASE 表达毫无意义。该 SQL 永远不会返回该错误。它会产生错误Incorrect syntax near SELECTWHEN SELECT 不是有效的语法。停止滴灌我们,给我们真正的 SQL和真正的问题。

标签: sql sql-server tsql select


【解决方案1】:

错误告诉你问题所在。您正在尝试将分隔的 varchar 传递给 int 列。

你可能更想要这个:

SELECT *
FROM dbo.YourTabLe YT
WHERE EXISTS (SELECT 1
              FROM dbo.OtherTable OT
              WHERE OT.UserID = 121
                AND OT.ID = YT.ID);

我个人更喜欢(NOT) EXISTS 而不是(NOT) IN,主要是因为NOT EXISTS 可以优雅地处理NULL 值,而NOT IN 则不能。

编辑:基于最新的编辑,但是,这是一个猜测,因为新的编辑有一个格式错误的查询:

SELECT *
FROM dbo.YourTabLe YT
WHERE (EXISTS (SELECT 1
              FROM dbo.OtherTable OT
              WHERE OT.UserID = 121
                AND OT.ID = YT.ID)
  AND  YT.changes = 40)     --Changes was prefiexed with table1, which doesn't exist in your sample query.
   OR NOT(YT.changes = 40); --I've therefore assumed it was meant to be your table

【讨论】:

  • 但您似乎无法在存在的情况下使用案例
  • "但是你好像不能在存在的情况下使用 case" 是的,你可以;它的实现与任何其他查询没有什么不同。如果你的尝试失败了,那是因为你错误地实现了它。但是,您的示例查询中没有 CASE 表达式,所以我不知道您的尝试是什么。但是在查询的WHERE 中放置CASE 是个坏主意。这将导致查询不可搜索。使用正确的布尔逻辑。
  • 我错过了那个部分,我更新了我的问题
  • 其中包含不会复制错误的 SQL,@TreeNode。
【解决方案2】:

In 接受子查询或表达式列表。您正在尝试即时构建表达式列表,这需要将in动态SQL 结合使用。使用子查询的正确语法是:

select * from table
    where ID in ( select ID FROM Tabl1 WHERE UserID = 121 )

【讨论】:

    【解决方案3】:

    你把事情复杂化了。这是一个简单的INNER JOIN 解决方案。您不需要CASE 语句,只需要WHERE 子句中的OR

    SELECT 
        t1.* 
    FROM table t1
    INNER JOIN Tabl1 t2 ON t1.ID = t2.ID
    WHERE (t2.changes = 40 AND t2.UserID = 121) 
        OR t2.changes <> 40
    

    【讨论】:

    • 不能使用join,它有自己的case语句
    • 您的问题没有提到使用CASE 声明。
    猜你喜欢
    • 2023-04-03
    • 2019-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-21
    • 1970-01-01
    相关资源
    最近更新 更多