【问题标题】:SQL return rows where count of children does not equal column valueSQL 返回子节点数不等于列值的行
【发布时间】:2009-12-15 00:41:55
【问题描述】:

我有一个名为 Item 的表,其中包含 ItemID (PK)、ItemName、ExpectedSubItems 列和另一个名为 SubItem 的表,其中包含 SubItemID (PK)、ItemID (FK)、SubItemName 列。

我想从 Item 中返回 SubItems 数量与 ExpectedSubItems 不同的所有行。

我尝试使用类似的东西:-

Select * From Item
Join SubItem on Item.ItemID = SubItem.ItemID
Where ExpectedSubItems = Count(SubItem.ItemID)

但这给了我错误:-

聚合可能不会出现在 WHERE 子句除非它在一个 包含在 HAVING 子句中的子查询 或选择列表,并且该列是 聚合是一个外部引用。

SQL 大师有什么想法吗?

【问题讨论】:

    标签: sql sql-server-2005


    【解决方案1】:

    你需要一个子查询

    select *
      from item
      where expectedsubtems <> (
        select count(*)
          from subitem
          where subitem.itemid = item.itemid
        )
    

    【讨论】:

      【解决方案2】:

      尝试:

      Select i.ItemId, i.ItemName
      From Item i
        Left Join SubItem s
           On s.ItemID  = i.ItemId
      Group By i.ItemId, i.ItemName, i.ExpectedSubItems
      Having Count(*) <> i.ExpectedSubitems
      

      【讨论】:

      • 你需要一个 GROUP BY 在某个地方
      • 是的,我确信有些响应者实际上是 24/7 全天候监控论坛并立即回答任何问题的机器人 :)
      • 可能是,我错误地将论坛本身用作编辑器,我发布了初步回复,然后一遍又一遍地编辑它,直到我对结果感到满意为止。但最近似乎我明白了响应速度如此之快......所以最初的答案必须完全正确(涵盖所有警告/边缘案例等)或者等到我完成编辑我发布的之前......
      • 实际上,我贿赂了一位SO 工作人员,当有人开始 输入问题时,他们会向我发送通知。 AJAX,你知道的。
      【解决方案3】:
      SELECT  ItemID
      FROM    Item
      JOIN    SubItem
      ON      SubItem.ItemID = Item.ItemID
      GROUP BY
              ItemID, ExpectedSubItems 
      HAVING  ExpectedSubItems <> COUNT(*)
      

      或者这个(这样您就不必按所有 Item 字段分组,这也适用于 0 预期子项)

      SELECT  Item.*
      FROM    Item
      CROSS APPLY
              (
              SELECT  NULL
              FROM    SubItem
              WHERE   SubItem.ItemID = Item.ItemID
              HAVING  ExpectedSubItems <> COUNT(*)
              ) S
      

      【讨论】:

        【解决方案4】:

        应该这样做:

        SELECT
             I.item_id,
             I.item_name,
             I.expected_subitems
        FROM
             Items I
        LEFT OUTER JOIN Sub_Items SI ON
             SI.item_id = I.item_id
        GROUP BY
             I.item_id,
             I.item_name,
             I.expected_subitems
        HAVING
             COUNT(SI.item_id) <> I.expected_subitems
        

        【讨论】:

        • 左外连接也可以获取没有子项的项目
        • 是的,我只是想提出任何简单的方法来避免预期子项为 1 而没有实际子项的问题。 COUNT(*) 最终仍会以 1 的形式返回,给出误报。
        • Tom H.:你可以使用COUNT(SubItem.ID)LEFT JOIN
        • 嘿...我知道当我进行更改时,我会回来看到有人留下了此评论。 :)
        【解决方案5】:

        尝试以下方法:

        select *
          from Item I
          LEFT OUTER JOIN (select ItemID, COUNT(*) as ActualSubItemCount
                             from SubItem
                             group by ItemID) S
            ON (I.ItemID = S.ItemID)
          where (S.ItemID IS NULL AND NVL(I.ExpectedSubItems, 0) <> 0) OR
                I.ExpectedSubItems <> S.ActualSubItemCount;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-09-23
          • 2018-08-07
          • 2011-05-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-01-23
          • 1970-01-01
          相关资源
          最近更新 更多