Vinzenz Mai: Matrix aus Tabellen

Beitrag lesen

Hallo Stoni,

Es kann ja sein, dass sich die Produkte mehr werden. Dann will ich nicht jedes mal den Abfragetext anpassen. Gibt es eine art Schleife, wie man den Teil

ja, gibt es.

MAX(CASE WHEN Produkt = 'Fernseher' THEN 'X' ELSE 'O' END) AS 'Fernseher',
    MAX(CASE WHEN Produkt = 'Kleid'     THEN 'X' ELSE 'O' END) AS 'Kleid',
    MAX(CASE WHEN Produkt = 'Lötkolben' THEN 'X' ELSE 'O' END) AS 'Lötkolben'

Ich habe die Aufgabe mit einer Stored Procedure gelöst. Diese ist speziell auf Deine Problemstellung mit meinen Tabellen hin getrimmt. Spannend wäre es, diese in eine allgemeine SP für beliebige Kreuztabellen umzuschreiben.
Mein Code ist sicherlich nicht der effizienteste, aber er tut, was er soll:

  
CREATE PROCEDURE kreuztabelle  
AS  
  
-- zwei lokale Variablen werden benötigt:  
DECLARE @sql varchar(8000)     -- um die SQL-Anweisung zusammenzubauen  
                               -- Länge ist auf 8000 Zeichen begrenzt.  
DECLARE @produkt varchar(255)  -- für das aktuelle Produkt  
                               -- sinnvollerweise gleiche Größe wie  
                               -- die Spalte aus der gelesen wird  
  
-- Zusammenbauen der SQL-Anweisung  
-- Zunächst der statische Vorspann  
SET @sql = 'SELECT  
    Lieferant'  
  
-- Einlesen der verschiedenen Produkte in einen [link:http://de.wikipedia.org/wiki/Cursor@title=Cursor] (CURrent Set Of Records)  
DECLARE C CURSOR FOR  
    -- DISTINCT vermeidet Dubletten  
    -- Produkte ohne Produktbezeichnung interessieren auch nicht :-)  
    SELECT DISTINCT Produkt FROM Produkte WHERE Produkt IS NOT NULL  
OPEN C  
  
-- Hole erste Zeile  
FETCH NEXT FROM C INTO @produkt  
-- Solange Ergebnisse da sind  
WHILE @@fetch_status = 0  
BEGIN  
    -- Behandle einfache Anführungszeichen  
    set @produkt = replace(@produkt, '''', '''''')  
  
    -- erzeuge für das Produkt eine Spalte nach dem bewährten Schema  
    SET @sql = @sql + ',  
    '  
        + 'MAX(CASE WHEN Produkt = '''  
        + @produkt  
        + ''' THEN ''X'' ELSE ''O'' END) AS '''  
        + @produkt  
        + ''''  
    -- hole nächste Zeile  
    FETCH NEXT FROM C INTO @produkt  
END  
CLOSE C         -- Schliesse Cursor  
DEALLOCATE C    -- Entferne den Cursorverweis  
                -- Speicher kann freigegeben werden  
  
-- Hänge den statischen Endteil an das SQL-Statement  
SET @sql = @sql + '  
FROM  
 (Lieferanten L  
INNER JOIN WerLiefertWas W ON L.l_id = W.l_id)  
INNER JOIN Produkte P ON W.p_id = P.p_id  
GROUP BY Lieferant'  
  
-- Führe das SQL-Statement aus  
EXEC (@sql)  

Nach einmaligem Ausführen dieser Anweisung kannst Du Deine Kreuztabelle einfach mit der Anweisung

EXEC kreuztabelle

erstellen

Freundliche Grüße

Vinzenz