123-pater
Goto Top

MS SQL Server - SQL Query zum vereinigen von Datensätzen

Kleine Knobelaufgabe:

Ich möchte im M$ SQL Server eine View erzeugen, die mir aus zwei Ergebnisdatensätzen einen Datensatz erzeugt.
Die relevanten Tabellen lassen sich durch mehrere JOINs kombinieren, jedoch stehen zwei zu trennenden Informationen in zwei Ergebnissen einer Spalte.

Nun muss ich noch zwei Ergebnissätze:
a b 1 c
a b 2 d

zusammenfassen zu
a b c d

oder, wer er weniger abstrakt mag, vin
Name Firma Typ Kontakt
Isabell Microsoft 1 +49 711 47114711
Isabell Microsoft 2 isabell@microsoft.com

zu:
Name Firma Telefon Email
Isabell Microsoft +49 711 47114711 isabell@microsoft.com

Die Vereinigung der Ergebnisse benötige ich für die ODBC Anbindung einer Telefonanlage (flache Struktur vorrausgesetzt).

Content-Key: 419769

Url: https://administrator.de/contentid/419769

Printed on: April 26, 2024 at 01:04 o'clock

Member: ukulele-7
ukulele-7 Feb 20, 2019 updated at 13:01:04 (UTC)
Goto Top
Das ist erstmal Pipikram:
SELECT t1.Name, t1.Firma,t1.Kontakt AS Telefon, t2.Kontakt AS Email
FROM tabelle t1 INNER JOIN tabelle t2 ON t1.Name = t2.Name AND t1.Firma = t2.Firma AND t2.Typ = 2 WHERE t1.Typ = 1
Aber:
Das setzt vorraus das immer beide Einträge gegeben sind. Ist dem nicht so musst du es anpassen.Gibt es einen Typ zu einem Namen und einer Firma mehrfach, musst du es anpassen. Kommen mehr Datenfelder dazu, solltest du es ggf. ganz anders aufbauen.

PS: Eine ID für die Kombination Name / Firma oder zumindest 2 IDs wären nützlich wenn wir das richtig aufbauen wollen. Die Kombination Name / Firma kann durch doppelte Schreibweise ja mehrfach vorhanden sein aber aus unterschiedlichen Objekten kommen.
Member: 123-Pater
123-Pater Feb 20, 2019 at 13:37:23 (UTC)
Goto Top
Krass, wusste nicht dass der Join auch auf derselben Tabelle wirkt.

Ja, das Beispiel war etwas arg reduziert.
In der Tat sind beide Typen (Telefon und Email optional), theoretisch könnten auch mehrere Einträge eines Types vorkommen.
Bei der Telefonnummer würde ich das mit Spalte 'Telefon01' und 'Telefon02' sogar berücksichtigen.

Eine ID für Firma hätte ich.
Eine weitere ID für Name ist nur innerhalb der Firma unique.

Jetzt hast Du mich neugierig gemacht, wie wir das 'richtig aufbauen' könnten....
Member: em-pie
em-pie Feb 20, 2019 at 16:00:39 (UTC)
Goto Top
Zitat von @123-Pater:

Krass, wusste nicht dass der Join auch auf derselben Tabelle wirkt.
Warum sollte das auch nicht gehen?
Einfach mal probieren face-wink

Eine ID für Firma hätte ich.
Eine weitere ID für Name ist nur innerhalb der Firma unique.
D.h. es gibt irgendwo noch eine Zuordnung zu NameID und FirmaID und bilden zusammen einen gemeinsamen Primärschlüssel, oder steht die FirmaID mit in der obigen Tabelle (deinem Auszug)?
Wenn ja, hast du deine Eindeutigkeit ja schon

Jetzt hast Du mich neugierig gemacht, wie wir das 'richtig aufbauen' könnten....
Mache einfach ein Left Join, statt Inner join und im Select abeitest du mit Case und IS Null:

Select 
 a.Col1
 , a.Col2
 , Case
  when b.Col3 IS NOT NULL Then b.Col3
  Else ''  
 End as Col3
 , b.Col4
From
 Table1 as a
Left Join Table2 as b on a.Col1 = b.Col1 and a.Col2 = b.Col2


Gruß
em-pie
Member: Crusher79
Crusher79 Feb 20, 2019 at 21:52:21 (UTC)
Goto Top
Würd ich so unterschreiben ;)

Kommt mir bekannt vor. hatt efürher mal für ERP System pogrammiert. Gab da aber 3 Tabellen. Nummer 2 war die Komm-Art und 3 standen dann die Daten (Telefon, Handy, E-Mail)

ID 0 gabs nict, war normal leer. Schön war immer wenn doch ein Nullsatz da war, und Nummer 0815 jeden zugeordnet wurde ... Autsch.
Member: ukulele-7
Solution ukulele-7 Feb 22, 2019 updated at 12:38:15 (UTC)
Goto Top
Sry hat etwas gedauert, wie wäre es mit:
WITH t AS (
	SELECT	ROW_NUMBER() OVER (PARTITION BY ID_Firma,ID_Person,Typ ORDER BY Kontakt) AS Zeile,
			ID_Firma,
			ID_Person,
			Typ,
			Kontakt
	FROM	tabelle
	WHERE	Typ IN ( 1,2 )
	), stamm AS (
	SELECT	DISTINCT
			ID_Firma,
			ID_Person,
			Firma,
			Name
	FROM	tabelle
WHERE	Typ IN ( 1,2 )
	)
SELECT	stamm.Firma,
		stamm.Name,
		t1.Kontakt AS Telefon1,
		t2.Kontakt AS Telefon2,
		t3.Kontakt AS Email
FROM	stamm
LEFT JOIN t t1
ON		stamm.ID_Firma = t1.ID_Firma
AND		stamm.ID_Person = t1.ID_Person
AND		t1.Typ = 1
AND		t1.Zeile = 1
LEFT JOIN t t2
ON		stamm.ID_Firma = t2.ID_Firma
AND		stamm.ID_Person = t2.ID_Person
AND		t2.Typ = 1
AND		t2.Zeile = 2
LEFT JOIN t t3
ON		stamm.ID_Firma = t3.ID_Firma
AND		stamm.ID_Person = t3.ID_Person
AND		t3.Typ = 2
AND		t3.Zeile = 1
Member: 123-Pater
123-Pater Mar 04, 2019 at 15:16:22 (UTC)
Goto Top
Örks, jetzt sind leider ein paar Tage den Neckar runter gekleckert, bis ich jetzt wieder antworten kann.
Ich hab' auch etwas gebraucht, um Deinen (Ukulele) Strukturvorschlag auf meinen Anwendungsfall zu übertragen.

Das verknüpfen der 3 Tabellen scheiterte noch in dem Fall, in dem es keinen verbindenden Eintrag in der 'Personen'-Tabelle gab.
Da hab ich dann noch eine UNION über Abfrage-Kontakt-Person und 'Abfrage-Kontakt-Firma' gemacht.
Die Idee der Sub-Query (WITH-clause) hab ich verwendet um Telefonkontakt und Email zu trennen (TYP=1, Type=2).

Vielen Dank, das hat sehr geholfen.

@Crusher: Ich hoffe, Du hast dort nicht am Tabellen-Design mitgewirkt. In der Tat geht es hier um 3 Tabellen.
;-P
Member: ukulele-7
ukulele-7 Mar 07, 2019 at 14:49:05 (UTC)
Goto Top
Vielleicht liefert ja auch eine Tabelle schon eindeutige Einträge für Firma/Person, das ist ja durchaus nicht unüblich face-smile


Bei mir im CRM gibts auch n:m-Beziehungen zwischen Unternehmen und Personen.