2012-11-06 13 views
11

Szukałem odpowiedzi na ten temat, ale nie mogę znaleźć dość, jak uzyskać ten odrębny zestaw rekordów na podstawie warunku. Mam tabelę zawierającą następujące dane przykładowe:SELECT DISTINCT HAVING Policz wyjątkowe warunki

Type Color Location Supplier 
---- ----- -------- -------- 
Apple Green New York ABC 
Apple Green New York XYZ 
Apple Green Los Angeles ABC 
Apple Red  Chicago  ABC 
Apple Red  Chicago  XYZ 
Apple Red  Chicago  DEF 
Banana Yellow Miami  ABC 
Banana Yellow Miami  DEF 
Banana Yellow Miami  XYZ 
Banana Yellow Atlanta  ABC 

chciałbym utworzyć kwerendę, która pokazuje liczbę unikalnych miejsc dla każdego odrębnego typu + Colour gdzie liczba unikalnych miejsc jest więcej niż 1, na przykład

Type Color UniqueLocations 
---- ----- -------- 
Apple Green 2 
Banana Yellow 2 

Uwaga: {Apple, Red, 1} nie pojawia się, ponieważ jest tylko jedno miejsce dla czerwonych jabłek (Chicago). Myślę, że mam ten (ale być może istnieje prostsza metoda). Używam:

SELECT Type, Color, Count(Location) FROM 
(SELECT DISTINCT Type, Color, Location FROM MyTable) 
GROUP BY Type, Color HAVING Count(Location)>1; 

Jak mogę utworzyć kolejne zapytanie, które zawiera listę Type, Color i Location dla każdego odrębnego Type,Color gdy liczba unikalnych miejscach do tego Type,Color jest większa niż 1? Powstały rekordów wyglądałby następująco:

Type Color Location 
---- ----- -------- 
Apple Green New York 
Apple Green Los Angeles 
Banana Yellow Miami 
Banana Yellow Atlanta 

Zauważ, że Apple, Red, Chicago nie pojawia się, ponieważ jest tylko 1 miejsce dla czerwonych jabłek. Dzięki!

Odpowiedz

13

Użyj COUNT(DISTINCT Location) i dołącz przeciwko podkwerendzie na Type i Color The GROUP BY i HAVING klauzul jak próbowano wykorzystać je będzie wykonać zadanie.

/* Be sure to use DISTINCT in the outer query to de-dup */ 
SELECT DISTINCT 
    MyTable.Type, 
    MyTable.Color, 
    Location 
FROM 
    MyTable 
    INNER JOIN (
    /* Joined subquery returns type,color pairs having COUNT(DISTINCT Location) > 1 */ 
    SELECT 
     Type, 
     Color, 
     /* Don't actually need to select this value - it could just be in the HAVING */ 
     COUNT(DISTINCT Location) AS UniqueLocations 
    FROM 
     MyTable 
    GROUP BY Type, Color 
    /* Note: Some RDBMS won't allow the alias here and you 
     would have to use the expanded form 
     HAVING COUNT(DISTINCT Location) > 1 
    */ 
    HAVING UniqueLocations > 1 
    /* JOIN back against the main table on Type, Color */ 
) subq ON MyTable.Type = subq.Type AND MyTable.Color = subq.Color 

Here is a demonstration

+0

Dzięki bardzo Michael! – vfxdev

3

można napisać swoją pierwszą kwerendę jak poniżej:

Select Type, Color, Count(Distinct Location) As UniqueLocations 
From Table 
Group By Type, Color 
Having Count(Distinct Location) > 1 

(jeśli używasz MySQL można użyć aliasu UniqueLocations w klauzuli having, ale na wiele inne systemy aliasy nie są jeszcze dostępne, ponieważ klauzula having jest oceniana przed klauzulą ​​select, w tym przypadku musisz powtórzyć liczbę na obu klauzulach).

I za drugim, istnieje wiele różnych sposobów, aby napisać, że może to być jeden:

Select Distinct Type, Color, Location 
From Table 
Where 
    Exists (
    Select 
     * 
    From 
     Table Table_1 
    Where 
     Table_1.Type = Table.Type 
     and Table_1.Color = Table.Color 
    Group By 
     Type, Color 
    Having 
     Count(Distinct Location) > 1 
) 
+0

Dzięki bardzo dużo fthiella! – vfxdev

+0

pierwszy bit nie działa. Nie rozpoznaje "UniqueLocations" –

+0

@EliPerpinyal jakiego używasz DBMS? – fthiella