Mehrere Felder vergleichen

pelesla

Benutzer
Beiträge
16
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!
 
Werbung:
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.
 
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 :)
 
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.
 
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!
 
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!
 
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
 
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.
 
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 :)
 
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
 
Werbung:
Zurück
Oben