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

Mehrere Felder vergleichen

Dieses Thema im Forum "Microsoft SQL Server" wurde erstellt von pelesla, 29 September 2015.

  1. pelesla

    pelesla Benutzer

    Hallo zusammen!

    Bin leider (noch) kein SQL-Profi und komme zurzeit nicht weiter..
    Folgendes Problem:

    ID1 ¦ ID2

    1 ¦ Alpha
    1 ¦ Beta
    2 ¦ Gamma
    2 ¦ Delta
    3 ¦ Alpha
    3 ¦ Beta
    3 ¦ Gamma
    4 ¦ Alpha
    4 ¦ Beta

    Gewünschte Ausgabe: ID1 mit 1 und 4, da sie die gleiche Anzahl ID2 haben und diese auch den gleichen Wert haben (Alpha und Beta).

    Die ID1 mit dem Wert 3 hat zwar auch Alpha und Beta in der ID2, jedoch auch noch das Gamma, deshalb fällt es weg.

    Anyone?

    Danke im Voraus!
     
  2. akretschmer

    akretschmer Datenbank-Guru

    Ich würde es in PG so machen, aber ich weiß nicht, ob das so 1:1 in M$SQL auch geht:

    Code:
    test=*# select * from pelesla ;
     id1 |  id2
    -----+-------
      1 | alpha
      1 | beta
      2 | gamma
      2 | delta
      3 | alpha
      3 | beta
      4 | alpha
      4 | beta
      3 | gamma
    (9 rows)
    
    test=*# select id2_group, array_agg(id1) from (select id1, array_agg(id2) as id2_group from pelesla group by id1) foo group by id2_group;
      id2_group  | array_agg
    --------------------+-----------
     {alpha,beta,gamma} | {3}
     {gamma,delta}  | {2}
     {alpha,beta}  | {4,1}
    (3 rows)
    
    Du kannst nun schauen, wie viele Elemente (und welche) in der 2. Spalte stehen.
     
  3. Distrilec

    Distrilec Datenbank-Guru

    Oracle-Syntax... MS SQL sollte aber was vergleichbares anbieten :)
    Code:
    With dat As (
    Select 1 as id1, 'Alpha' as id2 From dual Union All
    Select 1, 'Beta' From dual Union All
    Select 2, 'Gamma' From dual Union All
    Select 2, 'Delta' From dual Union All
    Select 3, 'Alpha' From dual Union All
    Select 3, 'Beta' From dual Union All
    Select 3, 'Gamma' From dual Union All
    Select 4, 'Alpha' From dual Union All
    Select 4, 'Beta' From dual)
    
    Select *
    From   dat d
    Where  (Select listagg(id2, ',') within Group(Order By id2 Asc)
            From   dat t
            Where  t.id1 = d.id1
            Group  By t.id1) In (Select listagg(id2, ',') within Group(Order By id2 Asc)
                                 From   dat t
                                 Where  t.id1 <> d.id1
                                 Group  By t.id1)
    
    Etwas zur Erklärung:
    1. Alle "id2" aufsteigend sortiert konkatenieren
    2. Mit allen "id2" aufsteigend sortiert und konkateniert vergleichen, die nicht die selbe id1 haben
    Edit:
    Beides nach id1 gruppiert

    Nicht optimiert... Sollte es aber erstmal tun :)
     
  4. pelesla

    pelesla Benutzer

    Vielen Dank für eure Vorschläge!
    Leider habe ich es noch immer nicht geschafft das Ganze ins SQL umzuschreiben.. :(
     
  5. ukulele

    ukulele Datenbank-Guru

    Ich hab mir mal aus Spass an der Freude die MS SQL Variante gezimmert:
    Code:
    CREATE TABLE dat(
         id1 INT,
         id2 VARCHAR(10)
         );
    
    INSERT INTO dat VAlUES(1,'Alpha');
    INSERT INTO dat VAlUES(1,'Beta');
    INSERT INTO dat VAlUES(2,'Gamma');
    INSERT INTO dat VAlUES(2,'Delta');
    INSERT INTO dat VAlUES(3,'Alpha');
    INSERT INTO dat VAlUES(3,'Beta');
    INSERT INTO dat VAlUES(3,'Gamma');
    INSERT INTO dat VAlUES(4,'Alpha');
    INSERT INTO dat VAlUES(4,'Beta');
    
    WITH test AS (
    SELECT   DISTINCT
         t1.id1,
         stuff((   SELECT   DISTINCT '' + t2.id2
             FROM   dat t2
             WHERE   t1.id1 = t2.id1
             FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,0,'') data
    FROM   dat t1
         )
    
    SELECT   t1.id1
    FROM   test t1
    INNER JOIN test t2
    ON     t1.data = t2.data
    AND     t1.id1 != t2.id1
    ORDER BY t1.id1
    
    Es gibt keine ligstagg() Funktion in MS SQL, XML PATH wird hier gerne als Ersatz verwendet.
     
  6. pelesla

    pelesla Benutzer

    Vielen Dank für die Hilfe!

    Ich versuche trotzdem das Ganze mit einer anderen Lösung zu lösen.
    Ziel wäre es das Ganze möglichst mit verschachtelten Selects in der where-Bedingung zu lösen.

    Trotzdem vielen Dank!
     
  7. pelesla

    pelesla Benutzer

    Morgen allerseits!

    Ich schon wieder :D

    Ich zerbreche mir noch immer den Kopf, wobei mir die Lösung von ukulele am besten gefallen hat.

    Code:
    SELECT  DISTINCT A.REPORT_ID,
         stuff((SELECT DISTINCT '' + B.REPORT_EL_ID
             FROM  REPORT_DAT B
             WHERE   A.REPORT_ID = B.REPORT_ID
             FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,0,'') data FROM REPORT_DAT A GROUP BY data HAVING COUNT(*) > 1
           
           
    
    Das wäre mMn die ideale Lösung , jedoch wird das 'data' nach dem GROUP BY nicht erkannt.
    Was muss man da genau machen, damit der Wert erkannt wird?

    Bin leider noch ein Anfänger und komm nicht immer auf eine Lösung.

    Vielen Dank im Voraus!
     
  8. ukulele

    ukulele Datenbank-Guru

    Was genau meinst du mit "wird nicht erkannt"?

    Ich würde sagen dein GROUP BY ist dort entweder deplatziert oder sollte A.REPORT_ID beinhalten, wobei dann das DISTINCT wieder überflüssig wäre.
    Code:
    SELECT   A.REPORT_ID,
         stuff((   SELECT DISTINCT '' + B.REPORT_EL_ID
             FROM  REPORT_DAT B
              WHERE  A.REPORT_ID = B.REPORT_ID
             FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,0,'') AS data
    FROM   REPORT_DAT A
    GROUP BY A.REPORT_ID,data
    HAVING COUNT(*) > 1
     
    pelesla gefällt das.
  9. pelesla

    pelesla Benutzer

    Führe ich folgenden Select aus, habe ich schon mal das Grundgerüst:

    Code:
    SELECT  A.REPORT_ID,
         stuff((SELECT DISTINCT '' + B.REPORT_EL_ID
             FROM  REPORT_DAT B
             WHERE   A.REPORT_ID = B.REPORT_ID
             FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,0,'') AS DATA FROM REPORT_DAT A GROUP BY A.REPORT_ID
             
    Ziel ist es nun, nur noch die doppelten Einträge aus der Spalte DATA auszugeben.
     
  10. ukulele

    ukulele Datenbank-Guru

    Und mein Code tut das nicht mit GROUP BY und HAVING?
     
  11. pelesla

    pelesla Benutzer

    Das 'data' im GROUP BY bleibt rot unterstrichen:
     

    Anhänge:

    • data.PNG
      data.PNG
      Dateigröße:
      11,2 KB
      Aufrufe:
      5
  12. Distrilec

    Distrilec Datenbank-Guru

    Du kannst Spaltenaliase nur in der Order By-Clause verwenden (logisch gesehen werden die nämlich NACH der Group By-Clause und VOR der Order By-Clause vergeben)
    D.h. du musst deine Spalte wohl oder übel ausschreiben :)
     
  13. ukulele

    ukulele Datenbank-Guru

    Recht hat er, habe ich nicht gesehen. Es ginge aber auch:
    Code:
    SELECT   t.REPORT_ID,
         t.data
    FROM   (
    
    SELECT  DISTINCT A.REPORT_ID,
      stuff((  SELECT DISTINCT '' + B.REPORT_EL_ID
      FROM  REPORT_DAT B
      WHERE  A.REPORT_ID = B.REPORT_ID
      FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,0,'') AS data
    FROM  REPORT_DAT A
    
         ) t
    GROUP BY t.REPORT_ID,t.data
    HAVING COUNT(*) > 1
     
    pelesla gefällt das.
  14. pelesla

    pelesla Benutzer

    Nun ist die Abfrage erfolgreich, jedoch kommen da keine Werte zurück:p
     
  15. akretschmer

    akretschmer Datenbank-Guru

    Man kann nicht immer alles haben ;-)
     
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