2012-05-14 4 views
6

Voglio contare due cose in condizioni diverse in una query.MySQL - Conteggio di due cose con condizioni diverse

SELECT COUNT(*) AS count FROM table_name WHERE name = ? 

e

SELECT COUNT(*) as count FROM table_name WHERE address = ? AND port = ? 

ho bisogno di avere un conteggio per le righe che hanno un certo indirizzo e determinata porta, e un conteggio separato per le righe che hanno un certo nome.

Mi rendo conto che avrei potuto fare

SELECT (COUNT*) as count FROM table_name WHERE (address = ? AND port = ?) OR name = ? 

Tuttavia questo è un singolo numero, e ho bisogno loro di essere separato in modo posso visualizzare un messaggio più preciso per l'utente.

Come potrei andare a fare questo? L'aiuto sarebbe apprezzato!

risposta

19

Che dire semplicemente:

SELECT 
    SUM(IF(name = ?, 1, 0)) AS name_count, 
    SUM(IF(address = ? AND port = ?, 1, 0)) AS addr_count 
FROM 
    table_name 
+0

Penso che questo sarebbe più o meno lo stesso di bobwienholt in termini di prestazioni, ma se uno di 'name',' address' o 'port' sono indicizzati, potrebbe essere più veloce aggiungere queste condizioni alla clausola WHERE:' WHERE name =? O (indirizzo =?AND port =?) ' –

4
SELECT SUM(CASE WHEN Name = ? THEN 1 ELSE 0 END) as name_match 
     , SUM(CASE WHEN Address = ? AND Port = ? THEN 1 ELSE 0 END) as address_match 
FROM table_name 
WHERE (address = ? AND port = ?) OR name = ? 
+0

Da quello che posso dire, questa query sarebbe più veloce rispetto agli altri due soluzioni. Sei d'accordo? – fruitcup

2

potrebbe essere più facile solo fare un dell'Unione:

SELECT COUNT(*) AS count FROM table_name WHERE name = ? 
    GROUP BY name 
UNION ALL 
SELECT COUNT(*) as count FROM table_name WHERE address = ? AND port = ? 
    GROUP BY address, port 
+0

Non ho mai usato UNION in precedenza, ma penso che la query di @ bobwienholt sarebbe più veloce. Cosa ne pensi? – fruitcup

+2

@DrAgonmoray È una buona domanda, e non lo so davvero ... Sono in realtà incline a pensare che in questo modo sarebbe più veloce ** se ** c'è un indice su * nome * così come * indirizzo * o * porta*. Il conteggio è molto veloce per una colonna indicizzata, mentre l'aggiunta di un'istruzione case potrebbe richiedere una scansione di tutte le righe. YMMV :) – McGarnagle

+1

Sono tendenzialmente d'accordo con la valutazione di dbaseman. Tuttavia, tendo ad usare il mio metodo nelle query in cui la clausola WHERE sta esaminando colonne diverse da quelle in cui sto contando i valori. In tal caso, il mio metodo sarebbe probabilmente più veloce. – bobwienholt