【问题标题】:Subquery returned more than 1 value with Iif conditions子查询在 Iif 条件下返回超过 1 个值
【发布时间】:2020-10-20 18:38:25
【问题描述】:
select *
from employee
where controllingoffice in (
    Iif(1=1, (select id from controllingoffice), (select id from controllingoffice where OwnerId=4))
)

消息 512,第 16 级,状态 1,第 1 行 子查询返回超过 1 个值。当子查询跟随 =、!=、、>= 或子查询用作表达式时,这是不允许的。

注意:两个子查询都返回多于 1 行

【问题讨论】:

  • 请熟悉“如何提出正确的问题”并提供一些有用的示例数据。无论如何,您可能想尝试如下修改查询:SELECT e.* FROM employee AS e INNER JOIN controllingoffice AS c ON c.id = e.controllingoffice AND c.id = CASE WHEN 1=1 THEN c.id ELSE 4 END.
  • 第二个查询不是第一个查询的子集吗?无论哪种方式,您都可以在最外层使用or 或两个查询中的union
  • 等等,既然 1 总是等于 1,那么 IIF 不是总是返回第一个参数吗?我根本没有得到那个代码示例。
  • @hsn 仅供参考,如果您想回答您需要与离开 cmets 的人互动的问题。

标签: sql-server subquery


【解决方案1】:

您的查询失败的原因是您的子查询返回多个值,而 iif() 函数期望其参数的标量结果。因为iif() 是一个函数,所以它计算为单个值而不是一组行。你不能像在过程语言中那样使用它来分支,所以你不能在这个意义上使子查询的执行有条件。

下面的子查询允许您在一个地方表达一次驾驶条件。如果这使用动态 SQL,那会很方便。我假设您的 1 = 1 是该输入的占位符。切换条件决定是返回所有行还是只返回单个OwnerId 的行:

select *
from employee
where controllingoffice in (
    select id from controllingoffice where
    <switch condition> or OwnerId = 4
);

顺便说一下,逻辑X or (~X)Y 简化为X or Y

您打算发生的情况的近似值如下所示:

select *
from employee
where
    1 = 1 and controllingoffice in (
        select id from controllingoffice
    )
 or 0 = 1 and controllingoffice in (
        select id from controllingoffice where OwnerId = 4
    );

【讨论】:

  • 我不认为这是正确的:据我了解,1=1merely 代表一个开关,所以我猜意图是either return all employees of all controllingoffices OR (if other switch state) return only of a selected office (in this case 4) - 您的示例将返回办公室 4 的所有员工只是......还是我在这里遗漏了什么? or 不等于 xor,对吧?
  • @Tyron78 正如我在末尾指出的那样,not X 部分逻辑是多余的(只要涉及空值。)OwnerId = 4 的行总是返回 有时它们只是开关关闭时唯一的行。
  • 是的,我不知道条件是像@input = 1 还是它只是作为动态 sql 插入。
  • 只需在 where 条件下将 * 替换为 Id 即可,非常感谢@shawnt00
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-23
  • 2016-04-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多