我有三个表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中创建这样的串联,还是我不得不求助于传统语言?
答案 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
有可能。但是就像我之前说的。太丑了。