合并三个表的结果而无需重复

时间:2019-08-16 21:08:06

标签: mysql join

我有三个表Users,Qualification&Work History。

USER_ID是Users表中的主键,在其他两个表中用作FK。

Users表与其他两个表具有一对多关系,即一个用户可以拥有多个学位以及许多过去的工作。

user_id  degree  year
-------  ------  ----
      1  BS      1950
      1  MS      1952
      1  Ph.D    1960
      2  BS      1990

user_id   Designation        From Year  To Year
-------  ------------------  ---------  -------   
      1   SSE                1955       1958
      1   System Architect   1960       1965
      2   Lab Engineer       1996       1997
      2   Lab Supervisor     1998       1999

我尝试使用INNER JOIN和LEFT JOINS,但它们无法创建所需的输出

SELECT users_qualification 
 INNER
  JOIN users_work 
    ON users_qualification.user_id = users_work.users_id
 WHERE user_id IN (SELECT USER_ID FROM users where job_id = 400)

[INNER] JOIN可以按预期工作,并在每个学位与每个工作经历之间建立​​了联系。但是我要寻找的是如下:

user_id  Degree  year  Designation        From Year  To Year
-------  ------  ----  -----------------  ---------  -------
     1   BS      1950  SSE                1955       1958
     1   MS      1952  System Architect   1960       1965
     1   Ph.D    1960 
     2   BS      1990  Lab Engineer       1996       1997
     2   ---     ---   Lab Supervisor     1998       1999

是否可以在(T-)SQL中创建这样的串联,还是我不得不求助于传统语言?

1 个答案:

答案 0 :(得分:0)

是的,可以使用SQL构造创建此结果集,但这很丑陋。

我们需要为每个user返回的行数定义一个有限的上限。我们可以使用内联视图为每​​个表返回的行分配顺序的“行号”。

也就是说,我们可以编写查询以返回这样的结果以进行鉴定

_rn  user_id  degree  year
---  -------  ------  ----
 1         1  BS      1950
 2         1  MS      1952
 3         1  Ph.D    1960
 1         2  BS      1990
^^^

这是针对job_history

_rn  user_id   Designation        From Year  To Year
---  -------  ------------------  ---------  -------   
 1         1   SSE                1955       1958
 2         1   System Architect   1960       1965
 1         2   Lab Engineer       1996       1997
 2         2   Lab Supervisor     1998       1999
^^^

我们可以针对user表编写外部查询,从而创建用户的重复副本,如下所示:

 user_id  _rn   
 -------  ---
       1   1
       1   2
       1   3
       1   4
       1   5
       1   6
       1   7
       2   1
       2   2
          ^^^

然后我们可以对其他两组执行外部联接。查询的形式如下:

 SELECT u.user_id
      , q.degree
      , q.year
      , j.designation 
      , j.from_year
      , j.to_year
   FROM user u 

  CROSS
   JOIN ( SELECT 1 AS _rn UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 5 ... ) r 

   LEFT 
   JOIN ( /* qualifications_rn_query */
        ) q
     ON q.user_id = u.user_id
    AND q._rn     = r._rn 

   LEFT 
   JOIN ( /* job_history_rn_query */
        ) j
     ON j.user_id = u.user_id
    AND j._rn     = r._rn

  WHERE ( q._rn IS NOT NULL OR j._rn IS NOT NULL )
  ORDER
     BY u.user_id 
      , r._rn 

有可能。但是就像我之前说的。太丑了。