Sql 在不重复值的情况下联接两个以上的表

Sql 在不重复值的情况下联接两个以上的表,sql,sql-server,Sql,Sql Server,我想加入三张桌子 我有三个表user、profession和education,其中“uid”是user表的主键,而其他两个表的外键。我想将这些表联接在一个表中生成结果 user profession education +------+-------+ +-----+----------+ +-----+---------+ | uid | uName | | uid | profName | | uid | eduName | +---

我想加入三张桌子

我有三个表user、profession和education,其中“uid”是user表的主键,而其他两个表的外键。我想将这些表联接在一个表中生成结果

user              profession           education
+------+-------+  +-----+----------+  +-----+---------+
| uid  | uName |  | uid | profName |  | uid | eduName |
+------+-------+  +-----+----------+  +-----+---------+
|    1 | aaa   |  |   1 | prof1    |  |   1 | edu1    |
|    2 | bbb   |  |   1 | prof2    |  |   1 | edu2    |
|    3 | ccc   |  |   2 | prof1    |  |   1 | edu3    |
|      |       |  |   3 | prof3    |  |   3 | edu4    |
|      |       |  |   3 | prof2    |  |     |         |
+------+-------+  +-----+----------+  +-----+---------+


Expected output
+------+-------+-----+----------+-----+---------+
| uid  | uName | uid | profName | uid | eduName |
+------+-------+-----+----------+-----+---------+
|    1 | aaa   |   1 | prof1    |   1 | edu1    |
| null | null  |   1 | prof2    |   1 | edu2    |
| null | null  |null | null     |   1 | edu3    |
|    2 | bbb   |   2 | prof1    | null| null    |
|    3 | ccc   |   3 | prof3    |   3 | edu4    |
| null | null  |   3 | prof2    | null| null    |
+------+-------+-----+----------+-----+---------+
我试着回答以下问题

select u.uid ,u.uName,p.uid , p.profName,e.uid,e.eduName
from  user  u inner join profession p on u.uid=p.pid
inner join education e on u.uid = e.uid
where u.uid=p.uid
and u.uid=e.uid
and i.uid=1
这给了我重复的值

+------+-------+-----+----------+-----+---------+
| uid  | uName | uid | profName | uid | eduName |
+------+-------+-----+----------+-----+---------+
|    1 | aaa   |   1 | prof1    |   1 | edu1    |
|    1 | aaa   |   1 | prof2    |   1 | edu1    |
|    1 | aaa   |   1 | prof1    |   1 | edu2    |
|    1 | aaa   |   1 | prof2    |   1 | edu2    |
|    1 | aaa   |   1 | prof1    |   1 | edu3    |
|    1 | aaa   |   1 | prof2    |   1 | edu3    |
+------+-------+-----+----------+-----+---------+
是否有一种方法可以在不重复值的情况下获得输出。
谢谢

您是否尝试了
distinct
关键字

select DISTINCT u.uid ,u.uName,p.uid , p.profName,e.uid,e.eduName
from  user  u inner join profession p on u.uid=p.pid
inner join education e on u.uid = e.uid
where u.uid=p.uid
and u.uid=e.uid
and i.uid=1

这件有点像猪

我同意@GordonLinoff的观点,理想情况下,本演示将在客户端完成

但是,如果我们希望在SQL中这样做,那么基本的方法是您必须获得每个用户将使用的最大行数(基于他们在每个professions and educations表中有多少条目的计数,然后是最大计数)

一旦我们有了每个用户所需的行数,我们就可以根据需要使用数字表(我已经为此提供了一个数字生成器)为每个用户展开行

然后,我们根据uid和联接表中条目的行号(相对于每个用户的“扩展”行的行号)联接上的每个表。然后我们选择相关的列,就这样完成了。出去的时候付钱给护士

WITH 
number_table(number) AS
(
    SELECT
        (ones.n) + (10 * tens.n) + (100 * hundreds.n) AS number

    FROM --available range 0 to 999
         (VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) AS ones(n)
        ,(VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) AS tens(n)
        ,(VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) AS hundreds(n)
)

,users(u_uid, userName) AS
(
    SELECT 1, 'aaa'
    UNION ALL
    SELECT 2, 'bbb'
    UNION ALL
    SELECT 3, 'ccc'
)

,professions(p_u_uid, profName) AS
(
    SELECT 1, 'prof1'
    UNION ALL
    SELECT 1, 'prof2'
    UNION ALL
    SELECT 2, 'prof1'
    UNION ALL
    SELECT 3, 'prof3'
    UNION ALL
    SELECT 3, 'prof2'
)
,educations(e_u_uid, eduName) AS
(
    SELECT 1, 'edu1'
    UNION ALL
    SELECT 1, 'edu2'
    UNION ALL
    SELECT 1, 'edu3'
    UNION ALL
    SELECT 3, 'edu4'
)

,row_counts(uid, row_count) AS
(
    SELECT u_uid, COUNT(u_uid) FROM users GROUP BY u_uid
    UNION ALL
    SELECT p_u_uid, COUNT(p_u_uid) FROM professions GROUP BY p_u_uid
    UNION ALL
    SELECT e_u_uid, COUNT(e_u_uid) FROM educations GROUP BY e_u_uid
)

,max_counts(uid, max_count) AS
(
    SELECT uid, MAX(row_count) FROM row_counts GROUP BY uid
)

SELECT 
    u_uid
    ,userName
    ,p_u_uid
    ,profName
    ,e_u_uid
    ,eduName

FROM
    max_counts 

INNER JOIN 
    number_table ON number BETWEEN 1 AND max_count

LEFT JOIN 
    (
        SELECT u_uid, userName, ROW_NUMBER() OVER (PARTITION BY u_uid ORDER BY userName) AS user_match
        FROM users
    ) AS users
    ON u_uid = uid
    AND number = user_match

LEFT JOIN 
    (
        SELECT p_u_uid, profName, ROW_NUMBER() OVER (PARTITION BY p_u_uid ORDER BY profName) AS prof_match
        FROM professions
    ) AS professions
    ON p_u_uid = uid
    AND number = prof_match

LEFT JOIN 
    (
        SELECT e_u_uid, eduName, ROW_NUMBER() OVER (PARTITION BY e_u_uid ORDER BY eduName) AS edu_match
        FROM educations
    ) AS educations
    ON e_u_uid = uid
    AND number = edu_match

ORDER BY 
     IIF(COALESCE(u_uid, p_u_uid, e_u_uid) IS NULL, 1, 0)   ASC --nulls last
    ,COALESCE(u_uid, p_u_uid, e_u_uid)                      ASC
    ,IIF(COALESCE(p_u_uid, e_u_uid) IS NULL, 1, 0)          ASC --nulls last
    ,COALESCE(p_u_uid, e_u_uid)                             ASC
    ,IIF(e_u_uid IS NULL, 1, 0)                             ASC --nulls last
    ,e_u_uid                                                ASC
结果是:

u_uid       userName p_u_uid     profName e_u_uid     eduName
----------- -------- ----------- -------- ----------- -------
1           aaa      1           prof1    1           edu1
NULL        NULL     1           prof2    1           edu2
NULL        NULL     NULL        NULL     1           edu3
2           bbb      2           prof1    NULL        NULL
3           ccc      3           prof2    3           edu4
NULL        NULL     3           prof3    NULL        NULL

您需要重复的值。SQL结果集没有固有的顺序。您想要的格式设置最好在应用程序层完成。查看结果,您没有重复行。。您的列具有重复的值。。因此,如果您需要对结果进行不同的格式化,则必须在客户端进行表示。空值的逻辑不清楚。如果prof1和prof2的uid相同,那么为什么prof1有aaa而prof2有null?这两行的结果差异的逻辑是什么?查询无法获得预期的结果,因为您的表有重复的值。请在您的代码上试用。那么,它不是在满足您的需要吗?