2017-10-11 2 views
0

Ich brauche Hilfe mit einer SQL-Abfrage. Ich habe zwei Tabellen, Computer und Produkt durch ComputerProduct verbunden. Jetzt möchte ich wissen, ob es Computer gibt, die denselben Namen mit dem gleichen primären Namen und sekundären Namen des Produkts haben. Das Ausführen der Abfrage für die folgenden Daten würde sowohl c1 als auch c2 zurückgeben. Wie kann ich Dubletten in einer Tabelle vermeiden?Suchen Sie nach Duplikaten in verwandten Tabellen

Computer 
----------------------- 
Id Name  
c1 computer1 
c2 computer1 
c3 computer2 

ComputerProduct 
----------------------- 
ComputerId ProductId 
c1   p1 
c1   p2 
c2   p1 
c2   p2 
c3   p1 
c3   p2 

Product 
----------------------- 
Id Name  Type 
p1 A1   Primary 
p2 a1010  Secondary 
+1

Beispieldaten ist groß, aber vergessen Sie nicht, uns das erwartete Ergebnis zu geben! – jarlh

+0

'COUNT()' mit 'GROUP BY' sollte helfen –

+0

@jarlh, Das Ergebnis muss C1 und C2 zurückgeben. –

Antwort

0

Ich habe versucht (auf MSSQL) eine Abfrage wie die folgende (vielleicht kann es vereinfacht werden ...).

In der inneren Abfrage werden alle Kombinationen extrahiert, wobei zwei Joins für die Typen 'Primary' und 'Secondary' verwendet werden.

Dann werden die Datensätze gruppiert und gezählt mit computer.name und Produktnamen.

Mit 'HAVING COUNT (*)> 1' werden nur die gewünschten Datensätze extrahiert, dh mit denselben Computernamen und Produktnamen.

Schließlich werden extrahiert nur die ID entsprechend extrahierten Computer.Name (s) und Produktnamen.

SELECT X.ID 
FROM COMPUTER X 
INNER JOIN COMPUTERPRODUCT Y1 ON X.ID=Y1.COMPUTERID 
INNER JOIN COMPUTERPRODUCT Y2 ON X.ID=Y2.COMPUTERID 
INNER JOIN PRODUCT Z1 ON Y1.PRODUCTID = Z1.ID AND Z1.[TYPE] ='Primary' 
INNER JOIN PRODUCT Z2 ON Y2.PRODUCTID = Z2.ID AND Z2.[TYPE] ='Secondary' 
WHERE EXISTS (SELECT 1 
       FROM (SELECT A.NAME, C1.NAME AS C1_NAME, C2.NAME AS C2_NAME, COUNT(*) AS RC 
         FROM COMPUTER A 
         INNER JOIN COMPUTERPRODUCT B1 ON A.ID=B1.COMPUTERID 
         INNER JOIN COMPUTERPRODUCT B2 ON A.ID=B2.COMPUTERID 
         INNER JOIN PRODUCT C1 ON B1.PRODUCTID = C1.ID AND C1.[TYPE]='Primary' 
         INNER JOIN PRODUCT C2 ON B2.PRODUCTID = C2.ID AND C2.[TYPE]='Secondary' 
         GROUP BY A.NAME, C1.NAME, C2.NAME 
         HAVING COUNT(*) >1 
        ) E WHERE X.NAME = E.NAME AND Z1.NAME =C1_NAME AND Z2.NAME =C2_NAME); 

Beispieldaten:

INSERT INTO COMPUTER VALUES ('c1','computer1'); 
INSERT INTO COMPUTER VALUES ('c2','computer1'); 
INSERT INTO COMPUTER VALUES ('c3','computer3'); 
INSERT INTO COMPUTER VALUES ('c4','computer1'); 

INSERT INTO COMPUTERPRODUCT VALUES ('c1','p1'); 
INSERT INTO COMPUTERPRODUCT VALUES ('c1','p2'); 
INSERT INTO COMPUTERPRODUCT VALUES ('c2','p1'); 
INSERT INTO COMPUTERPRODUCT VALUES ('c2','p2'); 
INSERT INTO COMPUTERPRODUCT VALUES ('c3','p1'); 
INSERT INTO COMPUTERPRODUCT VALUES ('c3','p2'); 
INSERT INTO COMPUTERPRODUCT VALUES ('c4','p1'); 
INSERT INTO COMPUTERPRODUCT VALUES ('c4','p3'); 

INSERT INTO PRODUCT VALUES ('p1','A1','Primary'); 
INSERT INTO PRODUCT VALUES ('p2','a1010','Secondary'); 
INSERT INTO PRODUCT VALUES ('p3','b2020','Secondary'); 

Ausgang:

ID 
c1 
c2 
1

Ich habe vor kurzem das gleiche Problem behandelt.

MySQL kann Tabellen erstellen, die keine Duplikate akzeptieren.

Sie können Ihre Tabelle ändern, um doppelte Werte zu entfernen.

ALTER TABLE ComputerProduct 
ADD UNIQUE (ComputerID); 

WICHTIG: DUPLIZIEREN Ihre Tabelle mit IT VOR MESSING SO laufen Sie Gefahr, KEINE Daten zu verlieren ...

Alles Gute und viel Glück, CrypticPug

1
with dat 
as (select c.id,c.name, p.prodtype,p.prodname 
    from computer c join computerProduct cp on c.id = cp.computerId 
        join product p on cp.productId = p.id) 
select * from computer 
where name in 
(
    select name from (select id,name,prodname from dat where prodtype='Primary')x 
    group by name 
    having count(*)>1 
    intersect 
    select name from (select id,name,prodname from dat where prodtype='Secondary')x 
    group by name 
    having count(*)>1 
) 
Verwandte Themen