Announcement

Collapse
No announcement yet.

Mehrere Datensatzergebnisse als Spalten

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Mehrere Datensatzergebnisse als Spalten

    Hallo,

    ich habe folgendes Problem:
    Stark vereinfacht, möchte ich aus einer Tabelle mit den Spalten "ID", "Flag" und "Name":

    ID | Flag| Name
    ------------------
    1 | 0 | Keiner
    2 | 1 | Test
    3 | 1 | Hallo
    4 | 0 | Der auch nicht
    5 | 0 | Unsichtbarer
    6 | 1 | Werner
    7 | 0 | Niemand
    8 | 1 | Hans
    9 | 1 | Peter

    Eine Datenmenge selektieren:

    Code:
    SELECT Name FROM tabelle WHERE Flag = 1
    Das Ergebnis soll aber so aussehen:

    Name1 | Name2 | Name3 | Name4 | Name5 | Name6 | Name7
    ------------------------------------------------------------------------
    Test | Hallo | Werner | Hans | Peter | NULL | NULL

    Das komplizierte daran ist, dass es immer 7 Spalten sein sollen (Also Ergebnis-Mengen < 7 Datensätze mit NULL "aufgefüllt" werden) und das ganze ein Teil eines Statetments ist (Subselect im SELECT-Block).

    Mein erster Ansatz war sowas:

    Code:
    SELECT TOP 1 Name FROM tabelle where ID in (Select Top 1 ID FROM tabelle where Flag = 1 ORDER BY ID ASC) ORDER BY ID DESC
    SELECT TOP 1 Name FROM tabelle where ID in (Select Top 2 ID FROM tabelle where Flag = 1 ORDER BY ID ASC) ORDER BY ID DESC
    SELECT TOP 1 Name FROM tabelle where ID in (Select Top 3 ID FROM tabelle where Flag = 1 ORDER BY ID ASC) ORDER BY ID DESC
    SELECT TOP 1 Name FROM tabelle where ID in (Select Top 4 ID FROM tabelle where Flag = 1 ORDER BY ID ASC) ORDER BY ID DESC
    SELECT TOP 1 Name FROM tabelle where ID in (Select Top 5 ID FROM tabelle where Flag = 1 ORDER BY ID ASC) ORDER BY ID DESC
    SELECT TOP 1 Name FROM tabelle where ID in (Select Top 6 ID FROM tabelle where Flag = 1 ORDER BY ID ASC) ORDER BY ID DESC
    SELECT TOP 1 Name FROM tabelle where ID in (Select Top 7 ID FROM tabelle where Flag = 1 ORDER BY ID ASC) ORDER BY ID DESC
    Nachteil: Bei Ergebnismengen < 7 wird der letzte Eintrag in alle weiteren eingefügt (durch die ORDER BY´s).

    Zweiter Ansatz:

    Code:
    WITH tmptbl AS (SELECT ROW_NUMBER() OVER(ORDER BY ID) AS RowNumber, ID FROM tabelle WHERE Flag = 1)
    SELECT Name FROM tmptbl WHERE Rownumber = 1
    WITH tmptbl AS (SELECT ROW_NUMBER() OVER(ORDER BY ID) AS RowNumber, ID FROM tabelle WHERE Flag = 1)
    SELECT Name FROM tmptbl WHERE Rownumber = 2
    WITH tmptbl AS (SELECT ROW_NUMBER() OVER(ORDER BY ID) AS RowNumber, ID FROM tabelle WHERE Flag = 1)
    SELECT Name FROM tmptbl WHERE Rownumber = 3
    WITH tmptbl AS (SELECT ROW_NUMBER() OVER(ORDER BY ID) AS RowNumber, ID FROM tabelle WHERE Flag = 1)
    SELECT Name FROM tmptbl WHERE Rownumber = 4
    WITH tmptbl AS (SELECT ROW_NUMBER() OVER(ORDER BY ID) AS RowNumber, ID FROM tabelle WHERE Flag = 1)
    SELECT Name FROM tmptbl WHERE Rownumber = 5
    WITH tmptbl AS (SELECT ROW_NUMBER() OVER(ORDER BY ID) AS RowNumber, ID FROM tabelle WHERE Flag = 1)
    SELECT Name FROM tmptbl WHERE Rownumber = 6
    WITH tmptbl AS (SELECT ROW_NUMBER() OVER(ORDER BY ID) AS RowNumber, ID FROM tabelle WHERE Flag = 1)
    SELECT Name FROM tmptbl WHERE Rownumber = 7
    Würde das richtige Ergebnis liefern, lässt sich aber (meines Wissens nach) nicht in ein Subselect integrieren.

    Dritter Ansatz:

    Code:
    SELECT TOP 1 Name FROM tabelle WHERE Flag = 1
    SELECT TOP 1 Name FROM tabelle WHERE Flag = 1 AND ID NOT IN (SELECT TOP 1 ID FROM tabelle WHERE Flag = 1)
    SELECT TOP 1 Name FROM tabelle WHERE Flag = 1 AND ID NOT IN (SELECT TOP 2 ID FROM tabelle WHERE Flag = 1)
    SELECT TOP 1 Name FROM tabelle WHERE Flag = 1 AND ID NOT IN (SELECT TOP 3 ID FROM tabelle WHERE Flag = 1)
    SELECT TOP 1 Name FROM tabelle WHERE Flag = 1 AND ID NOT IN (SELECT TOP 4 ID FROM tabelle WHERE Flag = 1)
    SELECT TOP 1 Name FROM tabelle WHERE Flag = 1 AND ID NOT IN (SELECT TOP 5 ID FROM tabelle WHERE Flag = 1)
    SELECT TOP 1 Name FROM tabelle WHERE Flag = 1 AND ID NOT IN (SELECT TOP 6 ID FROM tabelle WHERE Flag = 1)
    Nachteil: Da meine WHERE Bedingung deutlich umfangreicher ist, macht es das Statement unglaublich unübersichtlich. Außerdem müssen bei Anpassungen immer beide WHERE-Bedingungen angepasst werden.

    Gibt es da noch einen Einfacheren Weg? - Bei MySQL wäre dies ganz einfach per LIMIT(1,n) möglich.

    Gruß, Eight_ball

  • #2
    Keiner eine Idee dazu? :-(

    Comment


    • #3
      Das Problem nennt sich Transponierung und ist meist leider nur schwer umsetzbar. Das Größte Problem ist wohl die dynamische Anzahl von Spalten.
      Ich denke in T-SQL wäre so etwas wesentlich leichter umzusetzen als mit SQL.

      Comment


      • #4
        Die Anzahl der Spalten ist ja gerade fix, also nicht dynamisch. Ich habe es jetzt erstmal mit meiner letzten Variante umgesetzt, allerdings ist jeder Subselect (also pro Spalte) 1327 Zeichen lang.

        Übersichtlich ist das nicht gerade ;-)

        Comment


        • #5
          schau mal da, im Prinzip das gleiche

          Comment


          • #6
            Aber wenn Du einen neuen Benutzer hinzufügst, dann musst Du auch das SQL Kommando ändern. Das nenn ich nicht gerade fix

            Comment


            • #7
              Nein, da hast du meine Anforderung falsch verstanden: Ich möchte immer sieben Spalten haben. Wenn es mehr Namen (Benutzer) gibt, werden die ignoriert, gibt es weniger, werden die übrigen (wie oben schon beschrieben) mit NULL aufgefüllt.

              Comment

              Working...
              X