2017-12-31 308 views
2

を繰り返すことなくは、私は「uidは」ユーザーテーブルと他の二つのテーブルの外部キーの主キーである3つのテーブルのユーザー、専門職と教育を持って、私は3つのテーブルを結合したい値

を超える2つのテーブルを結合します。私が取得する方法はあり

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 | 
+------+-------+-----+----------+-----+---------+ 

私は私が値

+------+-------+-----+----------+-----+---------+ 
| 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 | 
+------+-------+-----+----------+-----+---------+ 

を複製できますクエリ

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 

次しようとした1つのテーブルにつながる生産するために、これらのテーブルに参加したいです値を繰り返さないで出力します。 ありがとう

+1

あなたが繰り返し値を求めています。 SQL結果セットには固有の順序付けはありません。必要な書式設定はアプリケーションレイヤーで行うのが最適です。 –

+0

あなたの結果を見ると、複写された行はありません。繰り返しの値を持つ列があります。結果の書式が異なる場合は、プレゼンテーションのクライアント側を操作する必要があります。 – scaisEdge

+0

nullのロジックが明確ではありません。 prof1とprof2のuidが同じ場合、なぜprof1にaaaがあり、prof2にnullがあるのですか?これらの2つの行の結果の違いについての論理は何ですか? – clinomaniac

答えて

0

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 
+0

はい私はあまりにもそれを試した.. –

+0

そう、それはあなたが必要としていないのですか? – CuriousGuy

2

これはブタのビットです。

@GordonLinoffに同意すると、このプレゼンテーションはクライアント側で行うのが理想です。

しかし、SQLで実行したい場合、基本的なアプローチは、各ユーザーが消費する行の最大数を取得する必要があるということです(それぞれのエントリの数に基づいて職業と教育の表、そしてこれらの数のうち最大のもの)。

各ユーザーに必要な行数を取得したら、必要に応じて数値表を使用して各ユーザーの行を展開します(目的に応じて数値ジェネレータが含まれています)。

次に、各ユーザーの「展開された」行の行番号を基準にして、結合された表の項目の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 
関連する問題