【问题标题】:join instances of same row连接同一行的实例
【发布时间】:2013-09-06 15:37:59
【问题描述】:

我有一个表 h 包含这样的数据(好吧,不是真的,这只是一个例子):

subj_id  q1  q2  q3  q4  q5  q6  num
      1   1   0   0   1   0   0    1
      1   0   0   0   1   0   0    2
      2   1   1   1   1   0   1    1
      2   1   0   0   1   0   0    2
      2   1   1   1   0   0   1    3
      3   0   1   0   0   1   1    1

我想总结每个 subj_id 的 q,得到如下输出:

subj_id   num1   num2   num3  
      1      2      1   null
      2      5      2      4
      3      3   null   null

但我得到以下信息:

subj_id   num1   num2   num3
      1      2      1   null
      1      2      1   null
      2      5      2      4
      2      5      2      4
      2      5      2      4
      3      3   null   null

汇总的行重复的次数与表中出现的 subj_id 一样多。

我的查询(postgres)如下所示:

select h.subj_id, n1.sum as num1, n2.sum as num2, n3.sum as num3 from ((( h
    left join (select subj_id, q1+q2+q3+q4+q5+q6 as sum from h where num=1) as n1 on h.subj_id=n1.subj_id)
    left join (select subj_id, q1+q2+q3+q4+q5+q6 as sum from h where num=2) as n2 on h.subj_id=n2.subj_id)
    left join (select subj_id, q1+q2+q3+q4+q5+q6 as sum from h where num=3) as n3 on h.subj_id=n3.subj_id) order by h.subj_id

左连接显然不是在这里使用的技巧,但是如何跳过重复的行?

提前致谢!

【问题讨论】:

    标签: sql postgresql left-join


    【解决方案1】:

    您的查询可以轻松修改为:

    with cte as (
        select subj_id, q1 + q2 + q3 + q4 + q5 + q6 as q, num
        from h
    )
    select
        subj_id,
        sum(case when num = 1 then q end) as num1,
        sum(case when num = 2 then q end) as num2,
        sum(case when num = 3 then q end) as num3
    from cte
    group by subj_id
    order by subj_id
    

    我认为计划会更好 - 根本不需要加入。

    => sql fiddle demo

    简要说明您的查询不工作的原因以及如何改进它:

    • 您会收到更多您想要的行,因为您的查询基本上是从表h 中选择每一行,然后从表hnum = 1, 2, 3 中对其求和。您的初始表中有 6 行,按逻辑您的结果中将有 6 行;
    • 如果您要进行这样的查询,我强烈建议您在内部查询中为表使用别名。我会帮助你理解查询。在某些情况下,它还可以帮助您避免错误的结果 - 请参阅我在本主题中的回答 - SQL IN query produces strange result

    -

    select
        h.subj_id, n1.sum as num1, n2.sum as num2, n3.sum as num3
    from h
        left join (
            select h1.subj_id, h1.q1+h1.q2+h1.q3+h1.q4+h1.q5+h1.q6 as sum
            from h as h1
            where h1.num=1
         ) as n1 on h.subj_id=n1.subj_id
        left join (
            select h2.subj_id, h2.q1+h2.q2+h2.q3+h2.q4+h2.q5+h2.q6 as sum
            from h as h2
            where h2.num=2
        ) as n2 on h.subj_id=n2.subj_id
        left join (
            select h3.subj_id, h3.q1+h3.q2+h3.q3+h3.q4+h3.q5+h3.q6 as sum
            from h as h3
            where h3.num=3
        ) as n3 on h.subj_id=n3.subj_id
    order by h.subj_id
    

    【讨论】:

    • 您的解决方案既漂亮又绝对正确,非常感谢您的帮助和指向 Fiddle 的链接(以及添加缺少的 sql 标签)。正如我的解决方案可能显示的那样,我不太喜欢 sql。您能否——为了完整起见——向我解释为什么我的脚本中的行重复了?谢谢!
    • @JanusEngstrøm 添加了一些解释,如果这还不够,请不要犹豫
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-24
    • 2017-05-08
    相关资源
    最近更新 更多