MS SQL 2000 Mehrere Zeilen mit unterschiedlichen Werten zu einer zusammenfassen
Nabend zusammen,
ich versuche aktuell eine View zu erstellen, bedauerlicherweise ist die zugrundeliegende Datenbankstruktur alles andere als Hilfreich. (Unabhängig vom Alter der Datenbank). Prinzipiell liegt mein Problem bei einer Tabelle der Datenbank, in der Telefondaten gespeichert werden. Da mir aktuell jedoch die Ideen ausgehen hoffe ich das ihr mir weiterhelfen könnt
Die Tabelle phone sieht wie folgt aus. (Ein Beispiel)
Die Struktur wie Sie sein müsste wäre jedoch in etwa so (wenn davon ausgegangen wird, das es max. 4 Nummern pro owner gibt)
Bisherige Überlegungen:
JOIN mit Subselect
Bei dieser Idee wollte ich die Tabelle auf sich selbst Joinen, jedoch in einer anderen Reihenfolge. Das Problem hierbei ist das ich zwar den letzten und den ersten Wert bekomme, den zweiten, dritten usw. jedoch nicht. (Einschränkung durch TOP)
Prinzipiell ist das bislang meine einzige brauchbare Idee gewesen, Dinge wie row_number, Aneinanderreihungen von Subselects usw. habe ich beim weiteren drüber nachdenken wieder verworfen, weil entweder die Funktion nicht unterstützt wird oder das ganze nicht funktioniert hat.
Ich hoffe ihr habt noch eine hilfreiche Idee, ich glaub ich drehe solange am Rad.. xD naja jedenfalls ärgert es mich das es nicht so funktioniert wie ich mir das vorgestellt habe...
Gruß und schon mal Danke
Dante Gabriel
ich versuche aktuell eine View zu erstellen, bedauerlicherweise ist die zugrundeliegende Datenbankstruktur alles andere als Hilfreich. (Unabhängig vom Alter der Datenbank). Prinzipiell liegt mein Problem bei einer Tabelle der Datenbank, in der Telefondaten gespeichert werden. Da mir aktuell jedoch die Ideen ausgehen hoffe ich das ihr mir weiterhelfen könnt
Die Tabelle phone sieht wie folgt aus. (Ein Beispiel)
phone_id | owner_id | phone |
---|---|---|
1 | 1 | Telefonnummer 1 |
2 | 1 | Telefonnummer 2 |
4 | 1 | Telefonnummer 3 |
7 | 3 | Telefonnummer 2 |
8 | 5 | Telefonnummer 1 |
9 | 5 | Telefonnummer 2 |
Die Struktur wie Sie sein müsste wäre jedoch in etwa so (wenn davon ausgegangen wird, das es max. 4 Nummern pro owner gibt)
owner_id | phone_1 | phone_2 | phone_3 | phone_4 |
---|---|---|---|---|
1 | Telefonnummer 1 | Telefonnummer 2 | Telefonnummer 3 | - |
3 | - | Telefonnummer 2 | - | - |
8 | Telefonnummer 1 | Telefonnummer 2 | - | - |
Bisherige Überlegungen:
JOIN mit Subselect
Bei dieser Idee wollte ich die Tabelle auf sich selbst Joinen, jedoch in einer anderen Reihenfolge. Das Problem hierbei ist das ich zwar den letzten und den ersten Wert bekomme, den zweiten, dritten usw. jedoch nicht. (Einschränkung durch TOP)
Prinzipiell ist das bislang meine einzige brauchbare Idee gewesen, Dinge wie row_number, Aneinanderreihungen von Subselects usw. habe ich beim weiteren drüber nachdenken wieder verworfen, weil entweder die Funktion nicht unterstützt wird oder das ganze nicht funktioniert hat.
Ich hoffe ihr habt noch eine hilfreiche Idee, ich glaub ich drehe solange am Rad.. xD naja jedenfalls ärgert es mich das es nicht so funktioniert wie ich mir das vorgestellt habe...
Gruß und schon mal Danke
Dante Gabriel
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 269657
Url: https://administrator.de/forum/ms-sql-2000-mehrere-zeilen-mit-unterschiedlichen-werten-zu-einer-zusammenfassen-269657.html
Ausgedruckt am: 23.12.2024 um 07:12 Uhr
9 Kommentare
Neuester Kommentar
Moin DanteGabriel,
das wird umständlich...
Ab MS-SQLServer 2005 gibt es für diese Anforderungen PIVOT/UNPIVOT-Features.
Dann könntest du deine Telefonliste in etwa so in die gewünschte Darstellung bringen:
ungetestet, sollte aber sinngemäß in die richtige Richtung gehen.
Leiser hat aber der SQLServer 2000 noch nix in Richtung Kreuztabellen implementiert (AFAIK).
Hier müsstest du dann so etwas über eine stored procedure abfackeln.
Eine der handelsüblichen Suchmaschinen liefert einige Implementierungsbeispiele.
Auf mssqltips ist eine kurze Linkliste für Beispiele.
Mit reinem SQL wirst du unter SQLServer 2000 nicht weit kommen, fürchte ich.
Ist das denn ein "eingefrorenes Projekt", für das keine Migration/kein Upgrade zu einer aktuelleren Version möglich ist?
Grüße
Biber
das wird umständlich...
Ab MS-SQLServer 2005 gibt es für diese Anforderungen PIVOT/UNPIVOT-Features.
Dann könntest du deine Telefonliste in etwa so in die gewünschte Darstellung bringen:
Select * from
(
SELECT owner_id , 'Phone_' || phone_id as phone_x, phone
from Telefonliste
) as t
PIVOT
( Max (phone)
FOR Phone_x in ( [Phone_1], [Phone_2], [Phone_3], [Phone_4])
) as ersterVersuch
ungetestet, sollte aber sinngemäß in die richtige Richtung gehen.
Leiser hat aber der SQLServer 2000 noch nix in Richtung Kreuztabellen implementiert (AFAIK).
Hier müsstest du dann so etwas über eine stored procedure abfackeln.
Eine der handelsüblichen Suchmaschinen liefert einige Implementierungsbeispiele.
Auf mssqltips ist eine kurze Linkliste für Beispiele.
Mit reinem SQL wirst du unter SQLServer 2000 nicht weit kommen, fürchte ich.
Ist das denn ein "eingefrorenes Projekt", für das keine Migration/kein Upgrade zu einer aktuelleren Version möglich ist?
Grüße
Biber
Moin Moin,
Versuchs mal mit (ich neine der SQL 2000 kannte rank() schon.):
Gruß L.
Zitat von @DanteGabriel:
Bedauerlicherweise gibt es nicht mal Unterscheidungsmerkmale in der Art der Nummer
(Nur ein Beschreibungsfeld was meistens nicht mal befüllt ist) aber so etwas wie Rufnumerntypen (Tel. , Fax, Mobil odä.)
gibt es ja nicht... sonst hätte ich das bereits im SELECT mit einer CASE Operation filtern können.
Das ist aus meiner Sicht das größere Problem dabei. Hier soltest du darübernachdenken ob es sich lohnt ein weiteres Feld "anzuflanschen".Bedauerlicherweise gibt es nicht mal Unterscheidungsmerkmale in der Art der Nummer
(Nur ein Beschreibungsfeld was meistens nicht mal befüllt ist) aber so etwas wie Rufnumerntypen (Tel. , Fax, Mobil odä.)
gibt es ja nicht... sonst hätte ich das bereits im SELECT mit einer CASE Operation filtern können.
ja MS SQL 2005 würde die Sache wirklich einfacher machen ... erheblich... naja aber irgendwie muss das mit MS SQL 2000 gehen.
Wobei ich mittlerweile auch immer mehr glaube das es mit reinem SQL nicht funktioniert...
Wobei ich mittlerweile auch immer mehr glaube das es mit reinem SQL nicht funktioniert...
Versuchs mal mit (ich neine der SQL 2000 kannte rank() schon.):
SELECT pp1.owner_id, pp1.Phone1, pp2.Phone2, pp3.Phone3, pp4.Phone4
FROM
(
SELECT p1.owner_id, p1.phone as 'Phone1'
FROM
(SELECT rank() OVER (PARTITION BY a.owner_id ORDER BY a.phone_id) as phonerank, a.owner_id, a.phone_id, a.phone
FROM Test_phone a
) as p1 WHERE p1.phonerank=1
) as pp1
LEFT JOIN
(
SELECT p2.owner_id, p2.phone as 'Phone2'
FROM
(SELECT rank() OVER (PARTITION BY a.owner_id ORDER BY a.phone_id) as phonerank, a.owner_id, a.phone_id, a.phone
FROM Test_phone a
) as p2 WHERE p2.phonerank=2
) as pp2
ON (pp1.owner_id=pp2.owner_id)
LEFT JOIN
(
SELECT p3.owner_id, p3.phone as 'Phone3'
FROM
(SELECT rank() OVER (PARTITION BY a.owner_id ORDER BY a.phone_id) as phonerank, a.owner_id, a.phone_id, a.phone
FROM Test_phone a
) as p3 WHERE p3.phonerank=3
) as pp3
ON (pp1.owner_id=pp3.owner_id)
LEFT JOIN
(
SELECT p4.owner_id, p4.phone as 'Phone4'
FROM
(SELECT rank() OVER (PARTITION BY a.owner_id ORDER BY a.phone_id) as phonerank, a.owner_id, a.phone_id, a.phone
FROM Test_phone a
) as p4 WHERE p4.phonerank=4
) as pp4
ON (pp1.owner_id=pp4.owner_id)
Gruß L.
Moin Logan000,
na, dann geht es sogar mit einem Inline-SELECT und ohne Rank() kürzer:
Sollte mit den obigen Beispieldaten ergeben:
Grüße
Biber
P.S. allerdings kann es weder bei Logans RANK() noch bei meinem Pseudo-Ranking eine "Phone_2"-Nummer geben, wenn es keine "Phone_1"-Nummer gibt.
Das ist eine Abweichung von der gewünschten Ausgabe oben.
na, dann geht es sogar mit einem Inline-SELECT und ohne Rank() kürzer:
select owner_id, max(phone_1) as phone_1, max(phone_2) as phone_2
, max(phone_3) as phone_3, max(phone_4) as phone_4 from (
select t1.owner_id, t1.Id
, case when (select count(*)+1 from telliste where owner_id=t1.owner_id and id < t1.id ) = 1 then phone else '' end as phone_1
, case when (select count(*)+1 from telliste where owner_id=t1.owner_id and id < t1.id ) = 2 then phone else '' end as phone_2
, case when (select count(*)+1 from telliste where owner_id=t1.owner_id and id < t1.id ) = 3 then phone else '' end as phone_3
, case when (select count(*)+1 from telliste where owner_id=t1.owner_id and id < t1.id ) = 4 then phone else '' end as phone_4
from telliste t1
) x group by owner_id
Sollte mit den obigen Beispieldaten ergeben:
OWNER_ID | PHONE_1 | PHONE_2 | PHONE_3 | PHONE_4
---------+-----------------+-----------------+-----------------+--------
1 | Telefonnummer 1 | Telefonnummer 2 | Telefonnummer 3 |
3 | Telefonnummer 2 | | |
5 | Telefonnummer 1 | Telefonnummer 2 | |
Grüße
Biber
P.S. allerdings kann es weder bei Logans RANK() noch bei meinem Pseudo-Ranking eine "Phone_2"-Nummer geben, wenn es keine "Phone_1"-Nummer gibt.
Das ist eine Abweichung von der gewünschten Ausgabe oben.
Moin DanteGabriel,
ich habe ja in meiner Variante auf Verwendung einer fertigen RANK()-Funktion verzichtet.
probier doch mal ein abgespecktes
... auf deiner Telefonliste.
Falls tatsächlich der heutige PK auf der Kombination von OWNER_ID und ID liegt, dann wird dieses Inline-Select auch gar nicht soooo inperformant sein.
Und zu dem P.S.: siehe ganz oben deine Wunsch-Ausgabe für OWNER_ID 3.
Grüße
Biber
ich habe ja in meiner Variante auf Verwendung einer fertigen RANK()-Funktion verzichtet.
probier doch mal ein abgespecktes
select t1.owner_id, t1.Id
. (select count(*)+1 from telliste where owner_id=t1.owner_id and id < t1.id )
, case when (select count(*)+1 from telliste where owner_id=t1.owner_id and id < t1.id ) = 1 then phone else '' end as phone_1
, case when (select count(*)+1 from telliste where owner_id=t1.owner_id and id < t1.id ) = 2 then phone else '' end as phone_2
from telliste t1
where owner_id < 100
Falls tatsächlich der heutige PK auf der Kombination von OWNER_ID und ID liegt, dann wird dieses Inline-Select auch gar nicht soooo inperformant sein.
Und zu dem P.S.: siehe ganz oben deine Wunsch-Ausgabe für OWNER_ID 3.
Grüße
Biber
Moin Dante Gabriel,
ich bin auch relativ zuversichtlich, dass die Strategie wie in meinem Kommentar von 14.00h zum Ziel führt.
Sicherlich auch, wenn du dem o.a. Statement noch ein "CREATE VIEW TelListePivot as (..)" voranstellst.
Falls es also klappt, setz' bitte den Beitrag auf "Gelöst".
Falls es nur in Ansätzen klappt, dann poste deine berichtigte, getestete und funktionierende Variante.
Dann haben auch andere mit einem vergleichbaren Problem etwas davon.
Grüße
Biber
ich bin auch relativ zuversichtlich, dass die Strategie wie in meinem Kommentar von 14.00h zum Ziel führt.
Sicherlich auch, wenn du dem o.a. Statement noch ein "CREATE VIEW TelListePivot as (..)" voranstellst.
Falls es also klappt, setz' bitte den Beitrag auf "Gelöst".
Falls es nur in Ansätzen klappt, dann poste deine berichtigte, getestete und funktionierende Variante.
Dann haben auch andere mit einem vergleichbaren Problem etwas davon.
Grüße
Biber