Information ausblenden
Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm

Kategorien richtig ausgeben

Dieses Thema im Forum "Microsoft SQL Server" wurde erstellt von Laines, 15 März 2015.

  1. Laines

    Laines Benutzer

    Hallo erst mal,
    Ich sitze schon seit Stunden an dieser warscheinlich simplen abfrage.
    Ich hole aus einer DB aus 3 Tabellen meine Daten mit LEFT JOIN funktioniert das perfekt.
    Ich hab nur ein Problem, auf dessen Lösung ich einfach nicht komme.
    Meine Abfrage lautet:
    Code:
    SELECT TOP 1000 ta.cArtNr AS Artikelnummer, ta.cName AS Bezeichnung,
    tk5.cName AS [Kat 1],
    tk4.cName AS [Kat 2],
    tk3.cName AS [Kat 3],
    tk2.cName AS [Kat 4],
    tk1.cName AS [Kat 5]
    FROM tartikel ta, tkategorieartikel tka
    LEFT JOIN tkategorie tk1 ON tk1.kKategorie = tka.kKategorie
    LEFT JOIN tkategorie tk2 ON tk2.kKategorie = tk1.kOberKategorie
    LEFT JOIN tkategorie tk3 ON tk3.kKategorie = tk2.kOberKategorie
    LEFT JOIN tkategorie tk4 ON tk4.kKategorie = tk3.kOberKategorie
    LEFT JOIN tkategorie tk5 ON tk5.kKategorie = tk4.kOberKategorie
    WHERE tka.kArtikel = ta.kArtikel
    ORDER BY ta.cArtNr ASC
    
    Nun kommt da aber folgendes heraus:
    Code:
    Artikelnummer Bezeichnung Kat 1 Kat 2 Kat 3 Kat 4 Kat 5
    100000 Testartikel NULL Kat 1 Kat 2 Kat 3 Kat 4
    100001 Testartikel NULL NULL Kat 1 Kat 2 Kat 3
    100002 Testartikel NULL Kat 1 Kat 2 Kat 3 Kat 4
    100003 Testartikel NULL NULL NULL Kat 1 Kat 2
    
    Am Ende soll aber folgendes heraus kommen:
    Code:
    Artikelnummer Bezeichnung Kat 1 Kat 2 Kat 3 Kat 4 Kat 5
    100000 Testartikel Kat 1 Kat 2 Kat 3 Kat 4
    100001 Testartikel Kat 1 Kat 2 Kat 3
    100002 Testartikel Kat 1 Kat 2 Kat 3 Kat 4
    100003 Testartikel Kat 1 Kat 2
    
    Kat 1 soll an erster stelle Kat 2 an zweiter ... usw.
    Kan ich das in einer Abfrage erreichen ??

    (Wenn ich jetzt noch wüsste wie ich im Forum eine Tabelle erstelle, wäre es etwas übersichtlicher)

    Danke und Gruß
    Laines
     
  2. akretschmer

    akretschmer Datenbank-Guru

    Mixe mal nicht impliziete und expliziet JOIN-Syntax, vielleicht reicht das schon.

    Also das FROM tartikel ta, tkategorieartikel tka ... WHERE tka.kArtikel = ta.kArtikel umformen in richtige JOIN-Syntax.
     
  3. akretschmer

    akretschmer Datenbank-Guru

    Ich versteh nicht, was Du erreichen willst. Dein Wunschresultat hat je Zeile eine unterschiedliche Anzahl Spalten. Das geht nicht.

    Kannst Du mal zur Illustration Beispieldaten zeigen? Und was rauskommen soll?
     
  4. Laines

    Laines Benutzer

    Hallo akretschmer,

    Danke für deine Antwort.
    Es ist eine Abfrage, die dann in eine CSV Datei Exportiert werden soll.

    Spalte 1 = Artikelnummer
    Spalte 2 = Bezeichnung
    Spalte 3 = Kategorie Ebene 1 (also die Oberkategorie)
    Spalte 4 - n Kategorie Ebene 2 - n ...

    Also:
    Artikelnummer | Bezeichnung | Kategorie 1 | Kategorie 2 | Kategorie 3 ...
    10000 | Artikel 1 | PC | Core i3 | Sonderangebot
    10001 | Artikel 2 | PC | Core i5 |
    10003 | Artikel 3 | Server | |

    In meiner Abfrage kommt erst einmal alles in umgekehrter Reihenfolge an
    Also:
    Artikelnummer | Bezeichnung | Kategorie 1 | Kategorie 2 | Kategorie 3 ...
    10000 | Artikel 1 | Sonderangebot | Core i3 | PC
    10001 | Artikel 2 | Core i5 | PC |
    10003 | Artikel 3 | Server | |
     
  5. akretschmer

    akretschmer Datenbank-Guru

    Also, Du bekommst jetzt dies:

    Code:
    test=*# select * from laines ;
      nr  |  name  | c1 |  c2  |  c3  |  c4  |  c5
    ------+-------------+----+------+------+------+------
     1000 | testartikel |  | kat1 | kat2 | kat3 | kat4
     1001 | testartikel |  |  | kat1 | kat2 | kat3
     1002 | testartikel |  | kat1 | kat2 | kat3 | kat4
     1003 | testartikel |  |  |  | kat1 | kat2
    (4 rows)
    
    und willst:

    Code:
    test=*# select nr, name, array_to_string(array[c1,c2,c3,c4,c5],' ') from laines ;
      nr  |  name  |  array_to_string
    ------+-------------+---------------------
     1000 | testartikel | kat1 kat2 kat3 kat4
     1001 | testartikel | kat1 kat2 kat3
     1002 | testartikel | kat1 kat2 kat3 kat4
     1003 | testartikel | kat1 kat2
    (4 rows)
    
    In PostgreSQL kannst das so direkt in eine CSV-Datei rausblasen. Ob es ähnlich in MSSQL geht weiß ich nicht.
     
  6. Laines

    Laines Benutzer

    Nein das war ein Missverständniss.
    Momentan werden die Daten so ausgegeben.
    Code:
    Artikelnummer | Bezeichnung | Kat 1 | Kat 2 | Kat 3 | Kat 4 | Kat 5
    -------------------+----------------+------+-------+-------+-------+-------
    100000 | Testartikel | NULL | Kat 4 | Kat 3 | Kat 2 | Kat 1
    100001 | Testartikel | NULL | NULL | Kat 3 | Kat 2 | Kat 1
    100002 | Testartikel | NULL | Kat 4 | Kat 3 | Kat 2 | Kat 1
    100003 | Testartikel | NULL | NULL | NULL | Kat 2 | Kat 1
    
    Sie sollen am Ende so ausgegeben werden
    Code:
    Artikelnummer | Bezeichnung | Kat 1 | Kat 2 | Kat 3 | Kat 4 | Kat 5
    -------------------+----------------+------+-------+-------+-------+-------
    100000 | Testartikel |Kat 1 | Kat 2 | Kat 3 | Kat 4 | NULL
    100001 | Testartikel | Kat 1 | Kat 2 | Kat 3 | NULL | NULL
    100002 | Testartikel | Kat 1 | Kat 2 | Kat 3 | Kat 4 | NULL
    100003 | Testartikel | Kat 1 | Kat 2 | NULL | NULL | NULL
    
    
     
  7. akretschmer

    akretschmer Datenbank-Guru

    Gut, dann halt so:

    Aus

    Code:
    test=*# select * from laines;
      nr  |  name  | c1 |  c2  |  c3  |  c4  |  c5
    ------+-------------+----+------+------+------+------
     1000 | testartikel |  | kat1 | kat2 | kat3 | kat4
     1001 | testartikel |  |  | kat1 | kat2 | kat3
     1002 | testartikel |  | kat1 | kat2 | kat3 | kat4
     1003 | testartikel |  |  |  | kat1 | kat2
    (4 rows)
    
    wird

    Code:
    test=*# select nr, name, array_agg[1] as kat1, array_agg[2] as kat2, array_agg[3] as kat3, array_agg[4] as kat4, array_agg[5] as kat5 from (select nr, name, array_agg(unnest) from (select nr, name, unnest(array[c1,c2,c3,c4,c5]) from laines order by nr, name, unnest nulls last) foo group by nr, name) bla;
      nr  |  name  | kat1 | kat2 | kat3 | kat4 | kat5
    ------+-------------+------+------+------+------+------
     1000 | testartikel | kat1 | kat2 | kat3 | kat4 |
     1001 | testartikel | kat1 | kat2 | kat3 |  |
     1002 | testartikel | kat1 | kat2 | kat3 | kat4 |
     1003 | testartikel | kat1 | kat2 |  |  |
    (4 rows)
    
    
    Machbar ist vieles, der Sinn mag dahingestellt sein...
     
  8. Distrilec

    Distrilec Datenbank-Guru

    Du hast das:

    Code:
    SELECT TOP 1000 ta.cArtNr AS Artikelnummer, ta.cName AS Bezeichnung,
    tk5.cName AS [Kat 1],
    tk4.cName AS [Kat 2],
    tk3.cName AS [Kat 3],
    tk2.cName AS [Kat 4],
    tk1.cName AS [Kat 5]
    FROM tartikel ta, tkategorieartikel tka
    LEFT JOIN tkategorie tk1 ON tk1.kKategorie = tka.kKategorie
    LEFT JOIN tkategorie tk2 ON tk2.kKategorie = tk1.kOberKategorie
    LEFT JOIN tkategorie tk3 ON tk3.kKategorie = tk2.kOberKategorie
    LEFT JOIN tkategorie tk4 ON tk4.kKategorie = tk3.kOberKategorie
    LEFT JOIN tkategorie tk5 ON tk5.kKategorie = tk4.kOberKategorie
    WHERE tka.kArtikel = ta.kArtikel
    ORDER BY ta.cArtNr ASC
    und willst:

    Code:
    SELECT TOP 1000 ta.cArtNr AS Artikelnummer, ta.cName AS Bezeichnung,
    tk1.cName AS [Kat 1],
    tk2.cName AS [Kat 2],
    tk3.cName AS [Kat 3],
    tk4.cName AS [Kat 4],
    tk15cName AS [Kat 5]
    FROM tartikel ta, tkategorieartikel tka
    LEFT JOIN tkategorie tk1 ON tk1.kKategorie = tka.kKategorie
    LEFT JOIN tkategorie tk2 ON tk2.kKategorie = tk1.kOberKategorie
    LEFT JOIN tkategorie tk3 ON tk3.kKategorie = tk2.kOberKategorie
    LEFT JOIN tkategorie tk4 ON tk4.kKategorie = tk3.kOberKategorie
    LEFT JOIN tkategorie tk5 ON tk5.kKategorie = tk4.kOberKategorie
    WHERE tka.kArtikel = ta.kArtikel
    ORDER BY ta.cArtNr ASC
    einfach die Reihenfolge der Spalten im Select ändern?....
     
  9. Laines

    Laines Benutzer

    Hallo,
    Die Reihenfolge ändern bringt nichts. Dann habe ich NULL Zellen bei Kat 1
    Mein Problem ist dass er mir mit dieser Abfrage den Kategoriebaum in umgekehrter Reihenfolge ausgibt.

    PC ist eigentlich die Oberkategorie danach kommt Core i3 usw
    Wenn ich die Reihenfolge der Spalten nur ändere, dann habe ich einmal PC als Kat 1 und bei einem Anderen Artikel der nur 2 Ebenen hat als Kat 2

    Also:
    Code:
    Artikelnummer | Bezeichnung | Kategorie 1 | Kategorie 2 | Kategorie 3 ...
    10000 | Artikel 1 | Sonderangebot | Core i3 | PC
    10001 | Artikel 2 | Core i5 | PC |
    10003 | Artikel 3 | Server | |
    
    Reihenfolge getauscht sieht so aus. Es soll aber PC immer in Kat 1 stehen
    Code:
    Artikelnummer | Bezeichnung | Kategorie 1 | Kategorie 2 | Kategorie 3 ...
    10000 | Artikel 1 | PC | Core i3 |Sonderangebot
    10001 | Artikel 2 | NULL | PC |Core i5 |
    10003 | Artikel 3 | Server | |
    
     
  10. ukulele

    ukulele Datenbank-Guru

    Also ein bischen verkorkst ist das schon aber ich glaube du suchst das hier:
    Code:
    SELECT    TOP 1000 t.*
    FROM    (
    
    SELECT    ta.cArtNr AS Artikelnummer,
            ta.cName AS Bezeichnung,
            tk5.cName AS [Kat 1],
            tk4.cName AS [Kat 2],
            tk3.cName AS [Kat 3],
            tk2.cName AS [Kat 4],
            tk1.cName AS [Kat 5]
    FROM    tartikel ta
    INNER JOIN tkategorieartikel tka ON    tka.kArtikel = ta.kArtikel
    LEFT JOIN tkategorie tk1 ON tk1.kKategorie = tka.kKategorie
    LEFT JOIN tkategorie tk2 ON tk2.kKategorie = tk1.kOberKategorie
    LEFT JOIN tkategorie tk3 ON tk3.kKategorie = tk2.kOberKategorie
    LEFT JOIN tkategorie tk4 ON tk4.kKategorie = tk3.kOberKategorie
    LEFT JOIN tkategorie tk5 ON tk5.kKategorie = tk4.kOberKategorie
    WHERE    tk5.cName IS NOT NULL
    
    UNION ALL
    
    SELECT    ta.cArtNr AS Artikelnummer,
            ta.cName AS Bezeichnung,
            tk4.cName AS [Kat 1],
            tk3.cName AS [Kat 2],
            tk2.cName AS [Kat 3],
            tk1.cName AS [Kat 4],
            NULL AS [Kat 5]
    FROM    tartikel ta
    INNER JOIN tkategorieartikel tka ON    tka.kArtikel = ta.kArtikel
    LEFT JOIN tkategorie tk1 ON tk1.kKategorie = tka.kKategorie
    LEFT JOIN tkategorie tk2 ON tk2.kKategorie = tk1.kOberKategorie
    LEFT JOIN tkategorie tk3 ON tk3.kKategorie = tk2.kOberKategorie
    LEFT JOIN tkategorie tk4 ON tk4.kKategorie = tk3.kOberKategorie
    LEFT JOIN tkategorie tk5 ON tk5.kKategorie = tk4.kOberKategorie
    WHERE    tk5.cName IS NULL
    AND        tk4.cName IS NOT NULL
    
    UNION ALL
    
    SELECT    ta.cArtNr AS Artikelnummer,
            ta.cName AS Bezeichnung,
            tk3.cName AS [Kat 1],
            tk2.cName AS [Kat 2],
            tk1.cName AS [Kat 3],
            NULL AS [Kat 4],
            NULL AS [Kat 5]
    FROM    tartikel ta
    INNER JOIN tkategorieartikel tka ON    tka.kArtikel = ta.kArtikel
    LEFT JOIN tkategorie tk1 ON tk1.kKategorie = tka.kKategorie
    LEFT JOIN tkategorie tk2 ON tk2.kKategorie = tk1.kOberKategorie
    LEFT JOIN tkategorie tk3 ON tk3.kKategorie = tk2.kOberKategorie
    LEFT JOIN tkategorie tk4 ON tk4.kKategorie = tk3.kOberKategorie
    LEFT JOIN tkategorie tk5 ON tk5.kKategorie = tk4.kOberKategorie
    WHERE    tk4.cName IS NULL
    AND        tk3.cName IS NOT NULL
    
    UNION ALL
    
    SELECT    ta.cArtNr AS Artikelnummer,
            ta.cName AS Bezeichnung,
            tk2.cName AS [Kat 1],
            tk1.cName AS [Kat 2],
            NULL AS [Kat 3],
            NULL AS [Kat 4],
            NULL AS [Kat 5]
    FROM    tartikel ta
    INNER JOIN tkategorieartikel tka ON    tka.kArtikel = ta.kArtikel
    LEFT JOIN tkategorie tk1 ON tk1.kKategorie = tka.kKategorie
    LEFT JOIN tkategorie tk2 ON tk2.kKategorie = tk1.kOberKategorie
    LEFT JOIN tkategorie tk3 ON tk3.kKategorie = tk2.kOberKategorie
    LEFT JOIN tkategorie tk4 ON tk4.kKategorie = tk3.kOberKategorie
    LEFT JOIN tkategorie tk5 ON tk5.kKategorie = tk4.kOberKategorie
    WHERE    tk3.cName IS NULL
    AND        tk2.cName IS NOT NULL
    
    UNION ALL
    
    SELECT    ta.cArtNr AS Artikelnummer,
            ta.cName AS Bezeichnung,
            tk1.cName AS [Kat 1],
            NULL AS [Kat 2],
            NULL AS [Kat 3],
            NULL AS [Kat 4],
            NULL AS [Kat 5]
    FROM    tartikel ta
    INNER JOIN tkategorieartikel tka ON    tka.kArtikel = ta.kArtikel
    LEFT JOIN tkategorie tk1 ON tk1.kKategorie = tka.kKategorie
    LEFT JOIN tkategorie tk2 ON tk2.kKategorie = tk1.kOberKategorie
    LEFT JOIN tkategorie tk3 ON tk3.kKategorie = tk2.kOberKategorie
    LEFT JOIN tkategorie tk4 ON tk4.kKategorie = tk3.kOberKategorie
    LEFT JOIN tkategorie tk5 ON tk5.kKategorie = tk4.kOberKategorie
    WHERE    tk2.cName IS NULL
    AND        tk1.cName IS NOT NULL
    
            ) t
    ORDER BY t.Artikelnummer ASC
    Auch wenn die Lösung wenig elegant ist ist sie zumindest leicht durchschaubar.
     
  11. Distrilec

    Distrilec Datenbank-Guru

    Du möchtest also wenn Kat1 leer ist Kat2 einfügen, bzw. wenn Kat2 auch leer ist Kat3 usw... ?
     
  12. Laines

    Laines Benutzer

    Genau !
    Auch wenn es nicht elegant ist, die Lösung oben funktioniert.

    Super !!!! vielen vielen Dank.
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden