2013-03-13 18 views
9

Ho tabelle di traino:MySQL Partecipa contare due tabelle e somma da seconda tabella

concessionari con alcuni campi e id chiave primaria

e indagini con seguenti campi id DEALER_ID costi

Ci sono diversi articoli in richieste per ogni rivenditore e devo contarli e sommare i costi. Ora ho solo il conteggio con questa affermazione:

SELECT a.*, Count(b.id) as counttotal 
FROM dealers a 
LEFT JOIN inquiries b on a.id=b.dealer_id 
GROUP BY a.id 
ORDER BY name ASC 

ma non ho idea di come sommare i costi della tabella b per ogni rivenditore. Qualcuno può aiutare? Grazie in anticipo

+3

Sapore di RDBMS per favore? –

+0

Mi spiace - il database è MySQL –

risposta

12

Si potrebbe utilizzare due sub-query:

SELECT a.* 
     , (SELECT Count(b.id) FROM inquiries I1 WHERE I1.dealer_id = a.id) as counttotal 
     , (SELECT SUM(b.cost) FROM inquiries I2 WHERE I2.dealer_id = a.id) as turnover 
FROM dealers a 
ORDER BY name ASC 

O

SELECT a.* 
    , COALESCE(T.counttotal, 0) as counttotal -- use coalesce or equiv. to turn NULLs to 0 
    , COALESCE(T.turnover, 0) as turnover  -- use coalesce or equiv. to turn NULLs to 0 
FROM dealers a 
LEFT OUTER JOIN (SELECT a.id, Count(b.id) as counttotal, SUM(b.cost) as turnover 
       FROM dealers a1 
       INNER JOIN inquiries b ON a1.id = b.dealer_id 
       GROUP BY a.id) T 
     ON a.id = T.id 
ORDER BY a.name 
+0

Seconda istruzione mi dà solo righe da una che hanno righe in b, non male per qualche motivo forse. Il primo è esattamente quello che sto cercando ed è molto più veloce dell'aggiunta del campo somma alla mia affermazione. Grazie per questo. –

+0

Modifica il JOINT INTERNO a un JOINT SINISTRO per ottenere tutto ... –

0

Basta aggiungere , Sum(b.costs) as costsTotal alla tua lista di selezione.

1

Se io sto capendo la tua domanda, tutto quello che dovete fare è aggiungere un SUM():

SELECT a.*, 
    Count(b.id) as counttotal, 
    sum(b.costs) TotalCost 
FROM dealers a 
LEFT JOIN inquiries b on a.id=b.dealer_id 
GROUP BY a.id 
ORDER BY name ASC 

Il mio suggerimento sarebbe quello di utilizzare una sottoquery per ottenere il count e la sum:

SELECT a.*, 
    b.countTotal, 
    b.TotalCosts 
FROM dealers a 
LEFT JOIN 
(
    select COUNT(ID) countTotal, 
     SUM(costs) TotalCosts, 
     dealer_id 
    from inquiries 
    group by dealer_id 
) b 
    on a.id=b.dealer_id 
ORDER BY name ASC 

Sto supponendo dalla tua query originale che stai usando MySQL. Suggerirei di utilizzare una sottoquery perché MySQL utilizza un'estensione di GROUP BY che consente agli elementi in un elenco selezionato di non aggregati e non inclusi nella clausola GROUP BY. Questo tuttavia può portare a risultati imprevisti perché MySQL può scegliere i valori che vengono restituiti. (Vedere MySQL Extensions to GROUP BY)

Dal MySQL Documenti:

MySQL estende l'uso di GROUP BY in modo che l'elenco di selezione può fare riferimento alle colonne nonaggregated non citati nella clausola GROUP BY. ... È possibile utilizzare questa funzione per ottenere prestazioni migliori evitando l'ordinamento e il raggruppamento non necessari delle colonne. Tuttavia, ciò è utile principalmente quando tutti i valori in ogni colonna non aggregata non denominata in GROUP BY sono uguali per ciascun gruppo. Il server è libero di scegliere qualsiasi valore da ciascun gruppo, quindi a meno che non siano gli stessi, i valori scelti sono indeterminati. Inoltre, la selezione dei valori di ciascun gruppo non può essere influenzata dall'aggiunta di una clausola ORDER BY. L'ordinamento del set di risultati si verifica dopo aver scelto i valori e ORDER BY non influisce sui valori scelti dal server.

+0

Sì, il primo era già il mio primo tentativo di realizzare ciò. Tuttavia non è riuscito a causa di un errore nella mia prima tabella. Ho provato di nuovo con la tua sintassi e funziona dopo qualche ricerca di errori. Ho provato già la seconda versione e funziona anche, ma mi dà in phpmyadmin '... 0 - 14 (~ 15 totali, ...' che dipende dalle spiegazioni fornite. Come ho capito, questo è solo un tipo di miglioramento delle prestazioni per utilizzare la sottoquery? Grazie! –

+0

@Ole_S la seconda versione impone il modo corretto di applicare un 'GROUP BY'. Le colonne in un elenco di selezione devono essere incluse in una funzione di aggregazione o in un' GROUP BY'. :) – Taryn

2
SELECT a.*, COUNT(b.id) AS counttotal, SUM(b.costs) AS total 
FROM dealers AS a 
LEFT JOIN inquiries AS b ON a.id=b.dealer_id 
GROUP BY a.id 
ORDER BY name ASC 
3
SELECT a.*, Sum(b.id) as TotalCost 
FROM dealers a 
LEFT JOIN inquiries b on a.id=b.dealer_id 
GROUP BY a.id 
ORDER BY name ASC 
0

makeing un tavolo sub, con i campi desiderati, e l'adesione, non la tabella completa renderà le cose easyer

selezionare A. *, B.count_total, b.costs_of_table
presso i rivenditori come
LEFT JOIN (

SELEZIONA aux.dealer_id, COUNT (aux.id) AS 'count_total', Sum (aux.costs) AS 'costs_of_table'
dalle indagini esempio AUX
GROUP BY DEALER_ID)

COME b SU a.id = b.dealer_id
WHERE (quello che volete)
ORDER BY nome ASC

dispiaciuto per la barra di ortografia eventuale

Problemi correlati