MSSQL - Ein Feld nach Kategorie in zwei Spalten teilen
10.01.2012
16:47:28 Uhr539 Aufrufe
4 Antworten
16:47:28 Uhr
4 Antworten
Noch nicht bewertet
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:
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ß
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:
01.
SELECT DISTINCT i.ID_Institution AS ID_Institution, ik.ID_KategorieKontakt, kk.Bezeichnung AS Region, i.Institutionsnummer AS Einrichtungscode, 02.
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, 03.
pg.Bezeichnung AS Personengruppe, k.Wert AS Telefon 04.
FROM VIEW_Institution AS i INNER JOIN 05.
InstitutionHatKategorieKontakt AS ik ON i.ID_Institution = ik.ID_Institution INNER JOIN 06.
KategorieKontakt as kk ON ik.ID_KategorieKontakt = kk.ID INNER JOIN 07.
InstitutionHatPerson AS ihp ON i.ID_Institution = ihp.ID_Institution INNER JOIN 08.
Person AS p ON ihp.ID_Person = p.ID INNER JOIN 09.
PersonengruppeHatPerson AS php ON ihp.ID_Person = php.ID_Person INNER JOIN 10.
Personengruppe AS pg ON pg.ID = php.ID_Personengruppe INNER JOIN 11.
PersonHatKommunikationsdaten AS phk ON p.ID = phk.ID_Person INNER JOIN 12.
Kommunikationsdaten AS k ON phk.ID_Kommunikationsdaten = k.ID INNER JOIN 13.
KategorieKommunikation AS kkom ON k.ID_KategorieKommunikation = kkom.ID 14.
15.
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 16.
(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 17.
(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 18.
(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 19.
ORDER BY RegionDerzeit 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ß
Biber schreibt am 10.01.2012 um 22:10:56 Uhr
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
Der zweite Teil spielt sich ja nur weiter oben in der Feldliste ab
Grüße
Biber
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
01.
... 02.
WHERE 03.
-- für alle und immer gilt 04.
( php.ID_Personengruppe='1DDC633B-D450-4E83-AEFA-C6C598B8F350' 05.
AND kkom.ID='9509F20D-1F48-4975-88C6-530B303CFDA2' 06.
AND phk.Standard=1 ) 07.
-- und außerdem gilt eingeleitet mit "AND". da zusätzliche Einschränkung... 08.
AND ik.ID_KategorieKontakt in 09.
( 'D926F6BC-0DFD-43E1-B462-869A60BE7871', 10.
'3F7CA9B8-6E31-48B5-85B3-39161B22D8BA', 11.
'82E205D2-388F-4AB4-8D1D-E1A903E3ED61', 12.
'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: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'.
01.
SELECT bla, blubb, etc, 02.
CASE 03.
WHEN kkom.ID='9509F20D-1F48-4975-88C6-530B303CFDA2' THEN k.Wert 04.
ELSE ' ' 05.
END as Telefon, 06.
CASE 07.
WHEN kkom.ID='5DBA8E8D-8BCD-44E3-9A49-A3813ECEEE03'. THEN k.Wert 08.
ELSE ' ' 09.
END as email, 10.
Sülzdibülz... 11.
FROM....Grüße
Biber
Yezariael schreibt am 11.01.2012 um 09:48:57 Uhr
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:
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:
01.
SELECT DISTINCT i.ID_Institution AS ID_Institution, ik.ID_KategorieKontakt, kk.Bezeichnung AS Region, i.Institutionsnummer AS Einrichtungscode, 02.
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, 03.
pg.Bezeichnung AS Personengruppe, 04.
CASE WHEN kkom.ID='9509F20D-1F48-4975-88C6-530B303CFDA2' THEN k.Wert ELSE '' END as Telefon, 05.
CASE WHEN kkom.ID='5DBA8E8D-8BCD-44E3-9A49-A3813ECEEE03' THEN k.Wert ELSE '' END as email 06.
FROM VIEW_Institution AS i INNER JOIN 07.
InstitutionHatKategorieKontakt AS ik ON i.ID_Institution = ik.ID_Institution INNER JOIN 08.
KategorieKontakt as kk ON ik.ID_KategorieKontakt = kk.ID INNER JOIN 09.
InstitutionHatPerson AS ihp ON i.ID_Institution = ihp.ID_Institution INNER JOIN 10.
Person AS p ON ihp.ID_Person = p.ID INNER JOIN 11.
PersonengruppeHatPerson AS php ON ihp.ID_Person = php.ID_Person INNER JOIN 12.
Personengruppe AS pg ON pg.ID = php.ID_Personengruppe INNER JOIN 13.
PersonHatKommunikationsdaten AS phk ON p.ID = phk.ID_Person INNER JOIN 14.
Kommunikationsdaten AS k ON phk.ID_Kommunikationsdaten = k.ID INNER JOIN 15.
KategorieKommunikation AS kkom ON k.ID_KategorieKommunikation = kkom.ID 16.
17.
WHERE 18.
-- für alle und immer gilt 19.
( php.ID_Personengruppe='1DDC633B-D450-4E83-AEFA-C6C598B8F350' AND phk.Standard=1 ) 20.
-- und außerdem gilt eingeleitet mit "AND". da zusätzliche Einschränkung... 21.
AND ik.ID_KategorieKontakt in ( 'D926F6BC-0DFD-43E1-B462-869A60BE7871', '3F7CA9B8-6E31-48B5-85B3-39161B22D8BA', 22.
'82E205D2-388F-4AB4-8D1D-E1A903E3ED61', 'C2A96AD6-0C50-4D3D-A985-F8FC24A5EBFB' ) 23.
AND kkom.ID in ('9509F20D-1F48-4975-88C6-530B303CFDA2', '5DBA8E8D-8BCD-44E3-9A49-A3813ECEEE03') 24.
ORDER BY Region
Biber schreibt am 12.01.2012 um 00:58:23 Uhr
Moin Yeziriael,
ein unappetitliches Datenmodell habt ihr da...
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
Der Vollständigkeit halber: ungetestet und irgendwie froh darüber, dass mir die Tabellen zum Testen fehlen.
Grüße
Biber
ein unappetitliches Datenmodell habt ihr da...
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
01.
02.
SELECT DISTINCT i.ID_Institution AS ID_Institution, 03.
ik.ID_KategorieKontakt, kk.Bezeichnung AS Region, 04.
i.Institutionsnummer AS Einrichtungscode, 05.
i.Name AS Name_Institution, i.Strasse, i.PLZ, i.Ort, 06.
ihp.ID_Person, p.Name AS Name, p.Vorname AS Vorname, 07.
php.ID_Personengruppe, pg.Bezeichnung AS Personengruppe, 08.
t.telefon, 09.
m.email 10.
FROM VIEW_Institution AS i 11.
INNER JOIN InstitutionHatKategorieKontakt AS ik ON i.ID_Institution = ik.ID_Institution 12.
INNER JOIN KategorieKontakt as kk ON ik.ID_KategorieKontakt = kk.ID 13.
INNER JOIN InstitutionHatPerson AS ihp ON i.ID_Institution = ihp.ID_Institution 14.
INNER JOIN Person AS p ON ihp.ID_Person = p.ID 15.
INNER JOIN PersonengruppeHatPerson AS php ON ihp.ID_Person = php.ID_Person 16.
INNER JOIN Personengruppe AS pg ON pg.ID = php.ID_Personengruppe 17.
INNER JOIN PersonHatKommunikationsdaten AS phk ON p.ID = phk.ID_Person 18.
INNER JOIN Kommunikationsdaten AS k ON phk.ID_Kommunikationsdaten = k.Id 19.
LEFT JOIN (SELECT kkom.id, kkom.Wert as Telefon 20.
FROM KategorieKommunikation AS kkom 21.
WHERE kkom.ID='9509F20D-1F48-4975-88C6-530B303CFDA2') as t 22.
ON k.ID_KategorieKommunikation = t.ID 23.
LEFT JOIN (SELECT kkom.id, kkom.Wert as eMail 24.
FROM KategorieKommunikation AS kkom 25.
WHERE kkom.ID='5DBA8E8D-8BCD-44E3-9A49-A3813ECEEE03') as m 26.
ON k.ID_KategorieKommunikation = m.ID 27.
WHERE 28.
-- für alle und immer gilt 29.
( php.ID_Personengruppe='1DDC633B-D450-4E83-AEFA-C6C598B8F350' AND phk.Standard=1 ) 30.
-- und außerdem gilt eingeleitet mit "AND". da zusätzliche Einschränkung... 31.
AND ik.ID_KategorieKontakt in ( 'D926F6BC-0DFD-43E1-B462-869A60BE7871', 32.
'3F7CA9B8-6E31-48B5-85B3-39161B22D8BA', 33.
'82E205D2-388F-4AB4-8D1D-E1A903E3ED61', 34.
'C2A96AD6-0C50-4D3D-A985-F8FC24A5EBFB' ) 35.
ORDER BY RegionDer Vollständigkeit halber: ungetestet und irgendwie froh darüber, dass mir die Tabellen zum Testen fehlen.
Grüße
Biber
Yezariael schreibt am 18.01.2012 um 13:37:05 Uhr
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
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












