【问题标题】:SQL Select count of items from a child table with a where clauseSQL 从带有 where 子句的子表中选择项目数
【发布时间】:2019-11-20 16:00:55
【问题描述】:

SQL 查询:

select c.cid, la.lid, b.bid, b.type 
from c c 
  left join la la on c.cid = la.cid
  left join b b on la.lid = b.lid
where b.type = 'Primary';

一共有三个表c -> la -> b

我需要任何给定“la”的“b”总数,但我需要在 where 子句中包含“b.type = 'Primary'”以用于其他目的。

b.type 有两种类型 - 主要和次要,但我想要计算“b”(主要和次要)的总数 有人可以提供任何提示吗?这对我来说将是一个很好的学习。谢谢。

sample data and desired o/p

【问题讨论】:

  • 可能与您的问题无关,但是:where b.type = 'Primary' 条件将您的两个外部联接都转回内部联接。
  • 如果您能提供一个简单的数据样本以及您的预期结果会更好。
  • 你一定要有where子句吗?
  • 是的,它是必需的。
  • 为什么查询中有表c?

标签: sql subquery outer-join


【解决方案1】:

试试这个:

SELECT 
  c.cid, 
  la.lid, 
  b.bid, 
  b.type,
  d.cbdi
FROM c c 
LEFT JOIN la la ON c.cid = la.lid
LEFT JOIN b b ON la.lid2 = b.lid2
LEFT JOIN (
            SELECT 
              la.lid,
              COUNT(b.bid) AS cbid
            FROM la la 
            LEFT JOIN b b ON la.lid2 = b.lid2
            GROUP BY la.lid
          ) d ON la.lid = d.lid
WHERE
  b.type = 'Primary';

【讨论】:

    【解决方案2】:

    由于子句where b.type = 'Primary',您不能根据附加的屏幕截图在所需的输出中拥有secondary 的行。请再次检查,您的要求似乎不清楚。

    【讨论】:

    • 是的 :) 我确信这个要求。我来看看有没有可能!
    • 哦,好吧,但我相信使用 where 子句 b.type = 'Primary' 是不可能的
    【解决方案3】:

    您似乎希望显示所有未聚合的行,但同时显示一个聚合(b 计数)。这是通过窗口函数完成的,在您的情况下为 COUNT OVER。

    select c.cid, la.lid, b.bid, b.type, count(*) over (partition by la.lid) as number_of_b
    from la
    join c on c.cid = la.cid
    join b on b.lid = la.lid
    order by c.cid, la.lid, b.bid;
    

    如果您想将此限制为具有至少一个主要b 的la,请相应地扩展此查询:

    select cid, lid, bid, type, number_of_b
    from
    (
      select
        c.cid, la.lid, b.bid, b.type,
        count(*) over (partition by la.lid) as number_of_b,
        max(case when b.type = 'Primary' then 1 else 0 end) over (partition by la.lid)
          as has_primary_b
      from la
      join c on c.cid = la.cid
      join b on b.lid = la.lid
      order by c.cid, la.lid, b.bid
    )
    where has_primary_b = 1;
    

    【讨论】:

      【解决方案4】:

      一种解决方案是将表 b 连接两次,以仅选择主要记录,然后将其全部计数。比如:

      select c.cid, la.lid, count(bt.id) 
      from c c 
        join la la on c.cid = la.cid
        join b b on la.lid = b.lid
        join b bt on la.lid = bt.lid 
      where b.type = 'Primary'
      group by c.cid, la.lid;
      

      【讨论】:

      • 您的查询缺少GROUP BY 子句。然后,样本数据结果(不幸的是只有一个链接图像)确实包含辅助 b 行,因此where b.type = 'Primary' 似乎不合适。然后,where b.type = 'Primary' 将外连接变为内连接,因此要么不要外连接,要么将条件放在它所属的 ON 子句中。
      • @Thorsten Kettner:你是对的,我编辑了我的答案。谢谢。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多