Announcement

Collapse
No announcement yet.

Mehrere identische DS in einer Datenzeile zusammenfassen

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

  • Mehrere identische DS in einer Datenzeile zusammenfassen

    Folgendes Problem:

    Ich habe eine GRUNDTABELLE:
    ID Name Vorname
    --------------------------------
    1234 Müller Peter
    5678 Schmitz Uwe
    9876 Meier Thomas

    Eine MERKMALTABELLE
    ID Merkmal-ID
    ------------------------------
    1234 2
    1234 3
    5678 2
    5678 3
    9876 1

    Eine MERKMALBESCHREIBUNGSTABELLE
    Merkmal-ID Merkmal-Beschreibung
    ------------------------------------
    1 Merkmal1
    2 Merkmal2
    3 Merkmal3


    1. Die Grundtabelle ist in einer "1 zu N" Beziehung mit der Merkmaltabelle über ID verbunden, so dass über eine "inner Join" folgendes

    Ergebnis entsteht:

    ID Name Vorname Merkmal-ID
    --------------------------------------------
    1234 Müller Peter 1
    1234 Müller Peter 2
    1234 Müller Peter 3
    5678 Schmitz Uwe 2
    5678 Schmitz Uwe 3
    9876 Meier Thomas 1

    2. Über ein weiteres "inner Join" mit der Merkmalbezeichnungs-Tabelle entsteht folgendes Ergebnis:
    ID Name Vorname Merkmal-ID Merkmal-Beschreibung
    --------------------------------------------------------------------
    1234 Müller Peter 1 Merkmal1
    1234 Müller Peter 2 Merkmal2
    1234 Müller Peter 3 Merkmal3
    5678 Schmitz Uwe 2 Merkmal2
    5678 Schmitz Uwe 3 Merkmal3
    9876 Meier Thomas 1 Merkmal1


    Zur besseren weiteren Verarbeitung möchte ich aber die verschiedene Merkmale gleicher Datensatzes in einer Datenzeile wie folgt haben:

    WUNSCHERGEBNIS:
    ===============
    ID Name Vorname Merkmal-ID Merkmal-Beschreibung1 Merkmal-Beschreibung2 Merkmal-Beschreibung3
    ---------------------------------------------------------------------------------
    1234 Müller Peter 1 Merkmal1 Merkmal2 Merkmal3
    5678 Schmitz Uwe 2 NULL Merkmal2 Merkmal3
    9876 Meier Thomas 1 Merkmal1 NULL NULL


    Ich habe dies über ein "left outer Join" für jede einzelne Merkmal-ID versucht. Sobald aber die Merkmal-ID "1" fehlt, werden auch die DS
    nicht gejoint. Ist die Merkmal-ID "2" vorhanden, kann aber wegen des fehlenden DS nicht mehr gejoint werden.

    Hat jemandeine Idee, wie dies lösbar ist.

    Zusammengefasst:
    Mehrere identische DS in einer Datenzeile zusammenfassen

    Zur besseren Tabellenübersicht s. Anlage
    Attached Files
    Zuletzt editiert von Christian Marquardt; 17.05.2012, 06:01. Reason: Text so formatiert, dass das Forumslayout nicht schaden nimmt

  • #2
    [HIGHLIGHT="SQL"]WITH GRUNDTABELLE (ID, Name, Vorname) AS
    ( SELECT 1234, 'Müller', 'Peter' UNION ALL
    SELECT 5678, 'Schmitz', 'Uwe' UNION ALL
    SELECT 9876, 'Meier', 'Thomas'
    )
    , MERMALTABELLE (ID, MerkmalID) AS
    ( SELECT 1234, 1 UNION ALL
    SELECT 1234, 2 UNION ALL
    SELECT 1234, 3 UNION ALL
    SELECT 5678, 2 UNION ALL
    SELECT 5678, 3 UNION ALL
    SELECT 9876, 1
    )
    , MERKMALBESCHREIBUNGSTABELLE (MerkmalID, Beschreibung) AS
    ( SELECT 1, 'Merkmal1' UNION ALL
    SELECT 2, 'Merkmal2' UNION ALL
    SELECT 3, 'Merkmal3'
    )
    SELECT G.*, M1.Beschreibung_1, M2.Beschreibung_2, M3.Beschreibung_3
    FROM GRUNDTABELLE AS G
    LEFT JOIN ( SELECT ID, Beschreibung AS Beschreibung_1
    FROM MERKMALBESCHREIBUNGSTABELLE AS B
    JOIN MERMALTABELLE AS M ON B.MerkmalID = M.MerkmalID
    AND M.MerkmalID = 1
    ) AS M1 ON M1.ID = G.ID
    LEFT JOIN ( SELECT ID, Beschreibung AS Beschreibung_2
    FROM MERKMALBESCHREIBUNGSTABELLE AS B
    JOIN MERMALTABELLE AS M ON B.MerkmalID = M.MerkmalID
    AND M.MerkmalID = 2
    ) AS M2 ON M2.ID = G.ID

    LEFT JOIN ( SELECT ID, Beschreibung AS Beschreibung_3
    FROM MERKMALBESCHREIBUNGSTABELLE AS B
    JOIN MERMALTABELLE AS M ON B.MerkmalID = M.MerkmalID
    AND M.MerkmalID = 3
    ) AS M3 ON M3.ID = G.ID

    -----------------------------------------------------------------------------
    -- ID Name Vorname Beschreibung_1 Beschreibung_2 Beschreibung_3
    -- ----------- ------- ------- -------------- -------------- --------------
    -- 1234 Müller Peter Merkmal1 Merkmal2 Merkmal3
    -- 5678 Schmitz Uwe NULL Merkmal2 Merkmal3
    -- 9876 Meier Thomas Merkmal1 NULL NULL [/HIGHLIGHT]
    PS: WITH dient nur zum Erzeugen temporärer Tabellen, ist vielleicht nicht in deinem DBMS implementiert

    Comment


    • #3
      mehrere identische ds in eine zeile zusammenfassen

      Liebe bis,

      Vielen, vielen dank für die geniale Lösung. Der Kniff der mir fehlte war der join nach dem kompletten left join, also der tabelle g mit dem ergebnis des ersten lft join statement.


      Noch eine Nachfrage. Wie würde man es lösen, wenn die Merkmalbeschreibungstabelle nicht nur 3 Elemente sondern hunderte hätte. Man müsse für jedes Mermal den left join wiederholen, was ab einer bestimmten Menge keinen Sinn mehr macht.

      Wäre schon, wenn e dazu auch eine Lösung gibt.

      Bisher habe ich nur 10 Merkmale, aber von Monat wächst dieser Bestand, so dass ich auf Dauer immer wieder ein Left join hinzufügen müsste.

      Trotzdem lieben dank für die ganze Mühe, da ich dieses Muster immer wieder auch in anderen Variantionen für komplexe Auswertungen benötige.

      Comment


      • #4
        Mmh, Du hast nach 3 Merkmalen gefragt und 3 bekommen.

        Dein Stichwort wäre Pivotisierung, Kreuztabellen oder ähnlich. Kreuztabellenabfragen konnte schon Access 97, im Serverbereich (reines SQL) sieht das nicht so gut aus. Eine allgemeine Lösung wirst Du nicht finden.
        Eine proprietäre schon, kommt auf Deine DB an.
        Gruß, defo

        Comment


        • #5
          a) Kreuztabelle mit dem Reporting-Tool erzeugen
          b) Dynamisches SQL..
          letzteres könnte unter MS-Sql-Server so aussehen:
          [HIGHLIGHT="SQL"]BEGIN TRAN;
          GO
          CREATE PROCEDURE dbo.Merkmale
          ( @Cols INT
          , @Debug INT = 0) AS
          BEGIN;
          SET NOCOUNT ON;
          DECLARE @Select NVARCHAR(MAX);
          DECLARE @Join NVARCHAR(MAX);
          DECLARE @Joins NVARCHAR(MAX);
          DECLARE @Column SYSNAME;
          DECLARE @Columns NVARCHAR(MAX);
          SET @Select = N'SELECT G.*';
          SET @Join = NCHAR(13)+N'LEFT JOIN ( SELECT ID, Beschreibung AS Beschreibung_1
          FROM MERKMALBESCHREIBUNGSTABELLE AS B
          JOIN MERMALTABELLE AS M ON B.MerkmalID = M.MerkmalID
          AND M.MerkmalID = 1
          ) AS M1 ON M1.ID = G.ID';
          SET @Column = NCHAR(13)+SPACE(9)+NCHAR(44)+SPACE(2)+N'M.Beschrei bung_1'
          DECLARE @Counter INTEGER;
          SET @Counter = 0;
          DECLARE @CntStr NVARCHAR(3)
          WHILE @Counter < @Cols
          BEGIN;
          SET @Counter = @Counter + 1;
          SET @CntStr = CAST (@Counter AS NVARCHAR(10))
          SET @Columns = ISNULL(@Columns,SPACE(0)) + REPLACE (@Column, NCHAR(49), @CntStr);
          SET @Joins = ISNULL(@Joins,SPACE(0)) + REPLACE (@Join, NCHAR(49), @CntStr);
          END;
          DECLARE @Stmt NVARCHAR(MAX);
          SET @Stmt = @Select + @Columns +NCHAR(13)+ N'FROM GRUNDTABELLE AS G' +@Joins;
          IF @Debug != 0 SELECT @Stmt FOR XML PATH (''), TYPE;
          ELSE EXEC sp_ExecuteSQL @Stmt;
          END;
          GO
          EXEC dbo.merkmale @Cols=5, @Debug=1;
          ROLLBACK; -- aufräumen...
          [/HIGHLIGHT]

          Comment

          Working...
          X