有条件地联接两个表

时间:2019-03-26 12:07:58

标签: sql-server

我有两个桌子。

  1. 父表:包含pid,pname和gender列
  2. 子表 child_parent 表包含子ID和父ID

我需要最终输出为:

childid, parentid, fathername, mothername (based on gender value)

我是SQL新手。

我已经在下面的查询中写了,但是没有得到预期的结果:

select 
    cc.cpid, p.pid, p.pname,
    case p.gender 
        when 'M' then 'father'
        when 'F' then 'Mother'
    end as Parenttype
from 
    parent p
join 
    child_parent cc on (cc.pid = p.pid) 
order by 
    cc.cpid

2 个答案:

答案 0 :(得分:2)

您遇到的问题之一是每个父级关系都有单独的一行。如果要将其合并为一行(每个父项具有单独的列),则必须使用聚合。

正如@Venkataraman_R所指出的,您可以将Child表连接到Parent表两次(一次是父亲,一次是母亲)。然后,您可以使用聚合函数将行“折叠”为1:

SELECT
    child_parent.cid,
    father_id = MIN(Father.pid),
    father_name = MIN(Father.pname),
    mother_id = MIN(Mother.pid),
    mother_name = MIN(Mother.pname)
FROM child_parent
    LEFT JOIN parent AS Father ON
        Father.pid = child_parent.pid
        AND Father.gender = 'M'
    LEFT JOIN parent as Mother ON
        Mother.pid = child_parent.pid
        AND Mother.gender = 'F'
GROUP BY child_parent.cid

注意每次我如何为父表赋予有意义的别名,就像@Venkataraman_R。

有了聚合函数,您现在有了一行:

+-----+-----------+-------------+-----------+-------------+
| cid | father_id | father_name | mother_id | mother_name |
+-----+-----------+-------------+-----------+-------------+
|   1 |         2 | Jack        |         3 | Josephine   |
+-----+-----------+-------------+-----------+-------------+

现在,请注意:该查询假定每个孩子最多有一个父亲,最多有一个母亲。有两个母亲或两个父亲的孩子(一夫多妻制,甚至更多)该怎么办?另外,对于单亲家庭,您将需要处理其中一列为空的情况。

此外,根据您要建模的内容,您可能需要考虑父母的性别既不是'M'也不是'F'的情况。

我有一个小提琴here。是Postgres,但语法大致相同。

答案 1 :(得分:1)

您可以使用其他条件编写条件连接,如下所示:

 select cc.cpid,p.pid, f.pname as father_name, m.pname as mother_name    
        from child_parent AS cc 
        join parent AS f on cc.pid=f.pid and gender = 'M'
        join parent AS m on cc.pid=m.pid and gender = 'F'             
        order by cc.cpid