yezariael
Goto Top

MSSQL - Ein Feld nach Kategorie in zwei Spalten teilen

Hi zusammen,

ich habe eine SQL-Abfrage (MSSQL) geschrieben, die bis auf ein Problem auch gut läuft.
Hintergrund ist, dass ich aus unserer Kundendatenbank Institutionen und zugeordnete Personen abrufen möchte, die bestimmten Kriterien (Kategorien) entsprechen.

Hier erst mal meine Abfrage:
SELECT DISTINCT i.ID_Institution AS ID_Institution, ik.ID_KategorieKontakt, kk.Bezeichnung AS Region, i.Institutionsnummer AS Einrichtungscode,
				 i.Name AS Name_Institution, i.Strasse, i.PLZ, i.Ort, ihp.ID_Person, p.Name AS Name, p.Vorname AS Vorname, php.ID_Personengruppe,
				  pg.Bezeichnung AS Personengruppe, k.Wert AS Telefon
FROM         VIEW_Institution AS i INNER JOIN
                      InstitutionHatKategorieKontakt AS ik ON i.ID_Institution = ik.ID_Institution INNER JOIN 
                      KategorieKontakt as kk ON ik.ID_KategorieKontakt = kk.ID INNER JOIN 
                      InstitutionHatPerson AS ihp ON i.ID_Institution = ihp.ID_Institution INNER JOIN
                      Person AS p ON ihp.ID_Person = p.ID INNER JOIN
                      PersonengruppeHatPerson AS php ON ihp.ID_Person = php.ID_Person INNER JOIN
                      Personengruppe AS pg ON pg.ID = php.ID_Personengruppe INNER JOIN
                      PersonHatKommunikationsdaten AS phk ON p.ID = phk.ID_Person INNER JOIN
                      Kommunikationsdaten AS k ON phk.ID_Kommunikationsdaten = k.ID INNER JOIN
                      KategorieKommunikation AS kkom ON k.ID_KategorieKommunikation = kkom.ID
                       
WHERE    (ik.ID_KategorieKontakt = '3F7CA9B8-6E31-48B5-85B3-39161B22D8BA') AND (php.ID_Personengruppe='1DDC633B-D450-4E83-AEFA-C6C598B8F350') AND (kkom.ID='9509F20D-1F48-4975-88C6-530B303CFDA2') AND phk.Standard=1 OR  
		 (ik.ID_KategorieKontakt = '82E205D2-388F-4AB4-8D1D-E1A903E3ED61') AND (php.ID_Personengruppe='1DDC633B-D450-4E83-AEFA-C6C598B8F350') AND (kkom.ID='9509F20D-1F48-4975-88C6-530B303CFDA2') AND phk.Standard=1 OR   
		 (ik.ID_KategorieKontakt = 'C2A96AD6-0C50-4D3D-A985-F8FC24A5EBFB') AND (php.ID_Personengruppe='1DDC633B-D450-4E83-AEFA-C6C598B8F350') AND (kkom.ID='9509F20D-1F48-4975-88C6-530B303CFDA2') AND phk.Standard=1 OR   
		 (ik.ID_KategorieKontakt = 'D926F6BC-0DFD-43E1-B462-869A60BE7871') AND (php.ID_Personengruppe='1DDC633B-D450-4E83-AEFA-C6C598B8F350') AND (kkom.ID='9509F20D-1F48-4975-88C6-530B303CFDA2') AND phk.Standard=1  
ORDER BY Region

Derzeit spuckt mir die Abfrage alle gewünschten Institutionen und alle Personen ordentlich aus.
Das Problem ergibt sich bei der Tabelle Kommunikationsdaten, hier gibt es drei Spalten: ID, Wert & ID_KategorieKommunikation
Wie ihr im WHERE-Teil meiner Abfrage sehen könnt habe ich die Kategorie schon mal eingegrenzt und zwar auf Telefon, aber ich benötige auch noch Email dazu. Die ID kommt aus der der Tabelle PersonHatKommunikationsdaten, der Wert steht in der Tabelle Kommunikationsdaten selbst und die Kategorie (von denen ich eben zwei brauche) aus der Tabelle KategorieKommunikation.

Meine Frage ist also nun, wie ich meine Abfrage anpassen muss, damit ich quasi sagen kann: Gib mir den Wert der Spalte k.Wert in der Spalte Telefon aus, wenn kkom.ID='9509F20D-1F48-4975-88C6-530B303CFDA2' und gib mir den Wert der Spalte k.Wert in der Spalte Email aus, wenn kkom.ID='5DBA8E8D-8BCD-44E3-9A49-A3813ECEEE03'.

Bin leider noch nicht wirklich fit in SQL und will ungern zwei getrennte Abfragen machen und die immer wieder in Excel zusammenfügen.

Ich hoffe, ich hab mein Problem halbwegs verständlich geschildert und ihr könnte mir helfen.

Danke schon mal.
Gruß

Content-Key: 178688

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

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

Member: Biber
Biber Jan 10, 2012 at 21:10:56 (UTC)
Goto Top
Moin Yezariael,

die Antwort ein bisschen getrennt in zwei Teilen.

Zum ersten die WHERE-Clausel... die kann ich so nicht stehen lassen.
Wenn du da draufschaust, dann stellst du fest, dass jeweils drei der vier * vier Bindungen immer gelten.

Als formuliere um in
...
WHERE 
-- für alle und immer gilt 
      ( php.ID_Personengruppe='1DDC633B-D450-4E83-AEFA-C6C598B8F350'   
          AND kkom.ID='9509F20D-1F48-4975-88C6-530B303CFDA2'  
           AND phk.Standard=1 )
-- und außerdem gilt eingeleitet mit "AND". da zusätzliche Einschränkung...  
AND    ik.ID_KategorieKontakt in
                          ( 'D926F6BC-0DFD-43E1-B462-869A60BE7871',  
                            '3F7CA9B8-6E31-48B5-85B3-39161B22D8BA',  
                            '82E205D2-388F-4AB4-8D1D-E1A903E3ED61',  
                            'C2A96AD6-0C50-4D3D-A985-F8FC24A5EBFB' )  

Der zweite Teil spielt sich ja nur weiter oben in der Feldliste ab
Meine Frage ist also nun, wie ich meine Abfrage anpassen muss, damit ich quasi sagen kann:
Gib mir den Wert der Spalte k.Wert in der Spalte Telefon aus, wenn kkom.ID='9509F20D-1F48-4975-88C6-530B303CFDA2'
und gib mir den Wert der Spalte k.Wert in der Spalte Email aus, wenn kkom.ID='5DBA8E8D-8BCD-44E3-9A49-A3813ECEEE03'.
-> auf SQL dann übersetzt:
SELECT bla, blubb, etc,
    CASE
     WHEN  kkom.ID='9509F20D-1F48-4975-88C6-530B303CFDA2'  THEN k.Wert    
      ELSE ' '    
END as Telefon,
    CASE
     WHEN  kkom.ID='5DBA8E8D-8BCD-44E3-9A49-A3813ECEEE03'.  THEN k.Wert    
      ELSE ' '    
END as email,
Sülzdibülz...
FROM....

Grüße
Biber
Member: Yezariael
Yezariael Jan 11, 2012 at 08:48:57 (UTC)
Goto Top
Ok, soweit klar und umgesetzt. Danke dafür schon mal!
Ein Problem stellt sich allerdings noch und zwar, dass in der WHERE-Clausel im Moment noch auf Telefon kkom.ID='9509F20D-1F48-4975-88C6-530B303CFDA2' abgegrenzt wird.
Nehme ich diese Abgrenzung raus, habe ich zwar Email und Telefon, beides auch in den entsprechenden Spalten, aber jede Person doch noch in zwei Zeilen.
Was muss ich denn noch ändern, damit jede Person in nur einer Zeile dargestellt wird?

Edit:
Aktueller Stand sieht so aus, Ergebnis aber weiterhin, dass Personen mit Email und Telefon in zwei Zeilen dargestellt werden:
SELECT DISTINCT i.ID_Institution AS ID_Institution, ik.ID_KategorieKontakt, kk.Bezeichnung AS Region, i.Institutionsnummer AS Einrichtungscode,
				 i.Name AS Name_Institution, i.Strasse, i.PLZ, i.Ort, ihp.ID_Person, p.Name AS Name, p.Vorname AS Vorname, php.ID_Personengruppe,
				  pg.Bezeichnung AS Personengruppe,
				  CASE WHEN  kkom.ID='9509F20D-1F48-4975-88C6-530B303CFDA2' THEN k.Wert ELSE '' END as Telefon,  
			      CASE WHEN  kkom.ID='5DBA8E8D-8BCD-44E3-9A49-A3813ECEEE03' THEN k.Wert ELSE '' END as email   
FROM         VIEW_Institution AS i INNER JOIN
                      InstitutionHatKategorieKontakt AS ik ON i.ID_Institution = ik.ID_Institution INNER JOIN 
                      KategorieKontakt as kk ON ik.ID_KategorieKontakt = kk.ID INNER JOIN 
                      InstitutionHatPerson AS ihp ON i.ID_Institution = ihp.ID_Institution INNER JOIN
                      Person AS p ON ihp.ID_Person = p.ID INNER JOIN
                      PersonengruppeHatPerson AS php ON ihp.ID_Person = php.ID_Person INNER JOIN
                      Personengruppe AS pg ON pg.ID = php.ID_Personengruppe INNER JOIN
                      PersonHatKommunikationsdaten AS phk ON p.ID = phk.ID_Person INNER JOIN
                      Kommunikationsdaten AS k ON phk.ID_Kommunikationsdaten = k.ID INNER JOIN
                      KategorieKommunikation AS kkom ON k.ID_KategorieKommunikation = kkom.ID
                       
WHERE  
-- für alle und immer gilt  
      ( php.ID_Personengruppe='1DDC633B-D450-4E83-AEFA-C6C598B8F350' AND phk.Standard=1 )   
-- und außerdem gilt eingeleitet mit "AND". da zusätzliche Einschränkung...   
AND    ik.ID_KategorieKontakt in ( 'D926F6BC-0DFD-43E1-B462-869A60BE7871', '3F7CA9B8-6E31-48B5-85B3-39161B22D8BA',  
									'82E205D2-388F-4AB4-8D1D-E1A903E3ED61', 'C2A96AD6-0C50-4D3D-A985-F8FC24A5EBFB' )  
AND kkom.ID in ('9509F20D-1F48-4975-88C6-530B303CFDA2', '5DBA8E8D-8BCD-44E3-9A49-A3813ECEEE03')  
ORDER BY Region
Member: Biber
Biber Jan 11, 2012 at 23:58:23 (UTC)
Goto Top
Moin Yeziriael,

ein unappetitliches Datenmodell habt ihr da... face-wink

Wenn sich diese doch voraussichtlich oft benötigten Sachverhalte nur durch 17 laufende Zentimeter JOINs ermitteln lassen, dann hat es irgendein Datenbank-Praktikant offensichtlich übertrieben mit der Normalisierung.
Merke: die fünfte Normalform ist in der Praxis weder normal noch die erste Wahl.

In der Theorie, falls ihr mit dieser Datenstruktur leben müsst, dann wäre ein möglicher Weg
 
SELECT DISTINCT i.ID_Institution AS ID_Institution, 
                ik.ID_KategorieKontakt, kk.Bezeichnung AS Region, 
                i.Institutionsnummer AS Einrichtungscode,
	       i.Name AS Name_Institution, i.Strasse, i.PLZ, i.Ort, 
              ihp.ID_Person, p.Name AS Name, p.Vorname AS Vorname, 
                php.ID_Personengruppe,  pg.Bezeichnung AS Personengruppe,
		t.telefon,
                m.email 
FROM         VIEW_Institution AS i 
         INNER JOIN InstitutionHatKategorieKontakt AS ik ON i.ID_Institution = ik.ID_Institution 
         INNER JOIN KategorieKontakt as kk ON ik.ID_KategorieKontakt = kk.ID 
         INNER JOIN InstitutionHatPerson AS ihp ON i.ID_Institution = ihp.ID_Institution 
         INNER JOIN Person AS p ON ihp.ID_Person = p.ID 
         INNER JOIN PersonengruppeHatPerson AS php ON ihp.ID_Person = php.ID_Person 
         INNER JOIN Personengruppe AS pg ON pg.ID = php.ID_Personengruppe 
         INNER JOIN PersonHatKommunikationsdaten AS phk ON p.ID = phk.ID_Person
         INNER JOIN Kommunikationsdaten AS k ON phk.ID_Kommunikationsdaten = k.Id
       LEFT JOIN (SELECT kkom.id, kkom.Wert as Telefon 
                 FROM KategorieKommunikation AS kkom 
                WHERE kkom.ID='9509F20D-1F48-4975-88C6-530B303CFDA2') as t  
                  ON k.ID_KategorieKommunikation = t.ID
       LEFT JOIN (SELECT kkom.id, kkom.Wert as eMail 
                 FROM KategorieKommunikation AS kkom 
                WHERE kkom.ID='5DBA8E8D-8BCD-44E3-9A49-A3813ECEEE03') as m  
                  ON k.ID_KategorieKommunikation = m.ID
WHERE  
-- für alle und immer gilt  
      ( php.ID_Personengruppe='1DDC633B-D450-4E83-AEFA-C6C598B8F350' AND phk.Standard=1 )   
-- und außerdem gilt eingeleitet mit "AND". da zusätzliche Einschränkung...   
AND    ik.ID_KategorieKontakt in ( 'D926F6BC-0DFD-43E1-B462-869A60BE7871',  
                 '3F7CA9B8-6E31-48B5-85B3-39161B22D8BA',  
		'82E205D2-388F-4AB4-8D1D-E1A903E3ED61',  
              'C2A96AD6-0C50-4D3D-A985-F8FC24A5EBFB' )  
ORDER BY Region

Der Vollständigkeit halber: ungetestet und irgendwie froh darüber, dass mir die Tabellen zum Testen fehlen.

Grüße
Biber
Member: Yezariael
Yezariael Jan 18, 2012 at 12:37:05 (UTC)
Goto Top
Hey Biber,

klappt so leider doch noch nicht, aber ich muss die Geschichte auch erst mal auf Eis legen, da der Aufwand den Nutzen schon fast übersteigt. Hab jetzt erst mal die Daten manuell in Excel bearbeitet und aus den zwei Zeilen eine gemacht und werde mich bei Gelegenheit noch mal an das Problem setzen.
Danke dir auf jeden Fall für deine Hilfe und eventuell melde ich mich hier noch mal.

Gruß
Yeza