2017-12-31 157 views
2

ich drei Tabellen anschließen mag,mehr als zwei Tabellen verknüpft werden, ohne Werte wiederholen

Ich habe drei Tabellen Benutzer, Beruf und Bildung, in denen „uid“ ist Primärschlüssel für Benutzertabelle und Fremdschlüssel für andere zwei Tabellen. Ich möchte diese Tabellen verbinden in einer einzigen Tabelle zu erzeugen, führen

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

ich Abfrage folgende versucht

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 

Was mich Werte

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

Gibt es eine Möglichkeit das bekommen duplizieren gibt Ausgabe mit nicht wiederholt die Werte. Danke

+1

Sie möchten die sich wiederholenden Werte. SQL-Ergebnismengen haben keine inhärente Reihenfolge. Die gewünschte Formatierung erfolgt am besten auf der Anwendungsebene. –

+0

mit Blick auf Ihr Ergebnis haben Sie Zeilen nicht dupliziert .. Sie haben Spalte mit rebead Werte .. so, wenn Sie andere Formatierung des Ergebnisses benötigen müssen Sie Client-Seite für die Präsentation – scaisEdge

+0

Ihre Logik für Nullen ist nicht klar. Wenn Sie die gleiche UID für prof1 und prof2 haben, warum hat dann prof1 aaa und prof2 null? Was ist die Logik für den Unterschied im Ergebnis für diese zwei Zeilen? – clinomaniac

Antwort

0

Haben Sie das Schlüsselwort distinct versucht?

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

ja ich habe das auch versucht .. –

+0

also, macht es nicht was du brauchst? – CuriousGuy

2

Bit eines Schweins dieser.

Ich stimme mit @GordonLinoff überein, dass diese Präsentation idealerweise auf der Client-Seite erfolgen würde.

Wenn wir es jedoch in SQL machen wollen, müssen Sie die maximale Anzahl von Zeilen, die von jedem Benutzer konsumiert werden, berechnen (basierend auf der Anzahl der Einträge in jedem einzelnen) der Berufe und Ausbildungskurse, und dann von diesen zählt die maximale Anzahl).

Sobald wir die Anzahl der Zeilen für jeden Benutzer benötigt haben, erweitern wir die Zeilen für jeden Benutzer nach Bedarf mithilfe einer Zahlentabelle (ich habe einen Zahlengenerator für diesen Zweck eingefügt).

Dann verbinden wir jede Tabelle auf, entsprechend der UID und der Zeilennummer des Eintrags in der verbundenen Tabelle relativ zur Zeilennummer der "erweiterten" Zeilen für jeden Benutzer. Dann wählen wir die relevanten Spalten aus, und das ist uns gelungen. Bezahle die Krankenschwester auf dem Weg nach draußen!

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 

Und die Ergebnisse:

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 
Verwandte Themen