2016-12-08 11 views
1

Ich arbeite seit einiger Zeit damit, kann aber keine Lösung finden, also können Sie mir vielleicht helfen.Probleme mit EXISTS und GROUP BY

Ich habe eine Tabelle mit 3 Spalten 'ID' 'Produkt' 'Code', ein Produkt kann wiederholt werden, aber ein Code muss für jedes Produkt eindeutig sein. Dies ist die Struktur der Tabelle:

CREATE TABLE table1 
    (`id` int, `product` varchar(10), `code` int) 
; 

INSERT INTO table1 
    (`id`, `product`, `code`) 
VALUES 
    (1, 'product1', 1), 
    (2, 'product1', 2), 
    (3, 'product1', 3), 
    (4, 'product2', 2), 
    (5, 'product2', 3), 
    (6, 'product3', 1), 
    (7, 'product3', 3) 
; 

Also, was ich versuche, eine Liste der Fälle zu tun ist, wenn ein Produktcode hat 1 und Code 2, bestimmten Wert in einer Antwort Spalte zeigen, wenn das Produkt hat nur Code 1 einen anderen Wert, wenn das Produkt Code 2 dann anderen Wert hat und wenn das Produkt weder Code 1 noch Code 2 hat, dann zeige einen anderen Wert (der Code 3 ist in diesem Beispiel irrelevant).

Dies ist, was ich

select product, 
    case 
    when exists(select 1 from table1 where code=1) = 1 
     and exists(select 1 from table1 where code=2) = 1 
    then 'Types are : 1,2' 
    when exists(select 1 from table1 where code=1) = 1 
     and exists(select 1 from table1 where code=2) = 0 
    then 'Type is : 1' 
    when exists(select 1 from table1 where code=1) = 0 
     and exists(select 1 from table1 where code=2) = 1 
    then 'Type is : 2' 
    else 
     'There are no types 1 or 2' 
    end as response 
from table1 
group by product 

Das Problem ist, dass resultset zeigt nur 'Typen sind: 1,2' so weit gehen, in meiner Antwort Spalte für product1, product2 und product3, ich glaube, dass die subselect in sucht nach allen Produkten (und nicht nach jedem Produkt), also gilt immer, dass Code 1 und Code 2 existieren.

Jede Hilfe oder Anweisung, die Sie zur Verfügung stellen könnten, ist sehr willkommen.

Danke fürs Lesen.

Fiddle Beispiel: http://sqlfiddle.com/#!9/25eb55/3

Antwort

3

Ihre Unterabfragen sind die gesamte Tabelle für den Code suchen Sie interessiert sind, nicht nur Zeilen mit dem gleichen Produkt.

Sie müssen eine korrelierte Unterabfrage verwenden, wenn die Unterabfrage nur für Zeilen mit demselben Produkt ausgewertet werden soll.

select p.product, 
    case 
    when exists(select 1 from table1 where code=1 and product=p.product) = 1 
     and exists(select 1 from table1 where code=2 and product=p.product) = 1 
    then 'Types are : 1,2' 
    when exists(select 1 from table1 where code=1 and product=p.product) = 1 
     and exists(select 1 from table1 where code=2 and product=p.product) = 0 
    then 'Type is : 1' 
    when exists(select 1 from table1 where code=1 and product=p.product) = 0 
     and exists(select 1 from table1 where code=2 and product=p.product) = 1 
    then 'Type is : 2' 
    else 
     'There are no types 1 or 2' 
    end as response 
from table1 as p 
group by product 

Ausgang:

+----------+------------------+ 
| product | response   | 
+----------+------------------+ 
| product1 | Types are : 1,2 | 
| product2 | Type is : 2  | 
| product3 | Type is : 1  | 
+----------+------------------+ 

aber ich vermeiden, in der Regel korrelierte Unterabfragen, weil sie für die Leistung so teuer sind. MySQL muss die Unterabfrage für jede Zeile in der äußeren Abfrage erneut ausführen.

Hier ist eine alternative Abfrage, die keine Unterabfragen verwendet, aber das gleiche Ergebnis:

SELECT product, 
    CASE GROUP_CONCAT(CASE WHEN code IN (1,2) THEN code ELSE NULL END ORDER BY code) 
    WHEN '1' THEN 'Type is : 1' 
    WHEN '1,2' THEN 'Types are: 1,2' 
    WHEN '2' THEN 'Type is : 2' 
    ELSE 'There are no types 1 or 2' 
    END AS response 
FROM table1 
GROUP BY product 
+1

Auf jeden Fall viel schneller, ich war besorgt über die Leistung aber nicht mehr. – None