【问题标题】:Subquery returned more than 1 value, error子查询返回超过 1 个值,错误
【发布时间】:2016-06-20 17:04:42
【问题描述】:

我收到以下错误消息;

子查询返回超过 1 个值。当子查询跟随 =、!=、、>= 或子查询用作表达式时,这是不允许的。

我遇到问题的代码部分位于我的 select 语句中;

    ,(SELECT COUNT(sch.startdate)
      FROM #test AS sch
      WHERE L.Id = sch.id
      GROUP BY sch.id, sch.startdate
      HAVING sch.startdate >= L.T_Start AND sch.startdate <= @END) AS SC

目前,如果该人在测试临时表中只有一条记录,但如果有两条记录就会崩溃。我知道我可以使用 Top 1 来限制它,但这不是我想要的。 L 来自主 select 语句。

好的,所以临时表有以下数据:

ID  startdate
1   2014-10-02
1   2014-11-02
2   2014-11-02

使用我的代码中的 TOP 1,我得到以下结果:

ID ~Other Stuff~  SC
1  ~~~~~~~~~~~~~  1
2  ~~~~~~~~~~~~~  1

但我想要返回的是:

ID ~Other Stuff~  SC
1  ~~~~~~~~~~~~~  2
2  ~~~~~~~~~~~~~  1

如何修改我的代码来实现这一点?

谢谢。

【问题讨论】:

  • 为了得到一个好的答案,您仍然需要显示“主”from 子句,而不仅仅是子查询。从概念上讲,您希望摆脱子查询中的 group by 并使用 to where 子句实质上通过 where sch.id = main.id 行将其连接到主查询。

标签: sql-server sql-server-2008 tsql


【解决方案1】:

这取决于您要计算的内容。您还可以将 HAVING 子句移到 WHERE 子句中(没有其他信息)。

如果您尝试从#test 中计算匹配的行数:

,(SELECT COUNT(*)
  FROM #test AS sch
  WHERE L.Id = sch.id
  AND sch.startdate >= L.T_Start AND sch.startdate <= @END) AS SC

如果您尝试计算唯一的开始日期值:

,(SELECT COUNT(DISTINCT sch.startdate)
  FROM #test AS sch
  WHERE L.Id = sch.id
  AND sch.startdate >= L.T_Start AND sch.startdate <= @END) AS SC

如果您尝试计算 (id, startdate) 的唯一组合,那么我认为您需要另一个级别的查询:

,(SELECT COUNT(*) FROM (
      SELECT sch.id, sch.startdate
      FROM #test AS sch
      WHERE L.Id = sch.id
      AND sch.startdate >= L.T_Start AND sch.startdate <= @END
      GROUP BY sch.id, sch.startdate) 
    AS X) AS SC

COUNT (Transact-SQL)

【讨论】:

    【解决方案2】:

    从 GROUP BY 中删除 sch.startdate。您想计算 StartDates,而不是 Group By 它们。

    【讨论】:

    • 我认为应该删除整个 GROUP BY,因为那时它仍将按 L.Id 分组。
    • 确实可以删除整个 Group By 并获得所需的结果,但我只提到 startdate 因为这是导致不良行为的部分。
    【解决方案3】:

    HAVING 用于过滤掉整个组的某些条件为真的组。通常这是来自您的分组的一些聚合,例如

    HAVING sum(amount) > 10
    

    你放

    HAVING sch.startdate >= L.T_Start --...
    

    这是在行级别拉 L.T_start(因为它不是聚合,也不在您的 GROUP BY 中)。

    取决于你想要做什么,要么

    将其移至 WHERE 子句(从语句预分组中过滤行)

    使其成为一个聚合(例如 HAVING max(sch.startdate > L.T_start) 等。

    按该条件分组,例如 通过...分组 -- ..., CASE 当 sch.startdate > L.T_start then 1 else 0 end -- ... 请注意,最后一个选项可能会给您两个组,因此您还应该将该 CASE 语句作为一列包含在您的选择列表中以识别差异。

    【讨论】:

      猜你喜欢
      • 2013-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多