2012-05-11 9 views
6

Data la tabella di foo:Come determinare se un valore compare in un gruppo per gruppo

Num Letter 
------------ 
1  A 
1  B 
1  B 
2  C 
3  A 
3  C 
3  D 

Se faccio SELECT * GROUP BY Num Io naturalmente ottenere qualcosa di simile:

Num Letter 
------------ 
1  A 
2  C 
3  A 

quello che avevo come definire questa a è:

Num Has_No_Letter_C 
--------------------- 
1  Yes 
2  No 
3  No 

C'è probabilmente un semplice SELECT IF() plu sa ORDER BY, ma non riesco a vedere in questo momento ...

Nel mio esempio del mondo reale, la tabella risultante è LEFT JOIN ed ad un altro tavolo e voglio essere in grado di respingere le voci No ma mantenere il NULL s se l'altra tabella bar ha un Num = 4 righe.

risposta

14

Usa SUM(condition) all'interno del IF:

SELECT Num, 
     IF(SUM(Letter = 'C'), 'Yes', 'No') AS Has_Letter_C 
FROM  my_table 
GROUP BY Num 

tuo JOIN diventa allora:

SELECT another_table.Num 
FROM  another_table LEFT JOIN my_table ON another_table.Num = my_table.Num 
GROUP BY another_table.Num 
HAVING my_table.Num IS NULL OR SUM(my_table.Letter = 'C') > 0 
+1

Grazie tu! Il primo funziona. Ho cambiato l'espressione in IF (SUM (Letter = 'C') = COUNT (Letter), 'Yes', 'No') 'come il mio esempio di vita reale ha bisogno di controllare tutte le C, e posso applicarlo a ottenere la mia domanda completa di lavoro. (Probabilmente è anche il momento in cui ho refactored e normalizzato le mie tabelle ...) –

+0

@ KenY-N: Per controllare se sono * tutti * 'C', sarebbe più semplice cercare qualsiasi valore che sia * non * C: 'SUM (Letter <> 'C')'. – eggyal

+0

Ah, certo! –

1

Se la tabella è LEFT JOIN, è possibile determinare facilmente se vi sono valori corrispondenti o meno.

Questo fa il lavoro se si prende il valore "C" in considerazione:

SELECT t1.num, 
      IF(ISNULL(t2.num),"Yes","No") AS "Has_No_Letter_C" 
FROM  yourtable AS t1 
LEFT JOIN yourtable AS t2 ON t1.num=t2.num AND t2.`letter` = "C" 
GROUP BY num; 
Problemi correlati