2013-03-13 13 views
9

Mam tabele holowniczych:MySQL Dołącz dwa stoły liczyć i suma z drugiej tabeli

dealerzy z niektórych pól i klucz podstawowy identyfikator

i zapytania z następujących dziedzin id dealer_id Koszty

Istnieje kilka pozycji w pytaniach dla każdego dealera i muszę je policzyć i zsumować koszty. Teraz mam tylko liczyć się z tym stwierdzeniem:

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 

ale nie mam pojęcia jak do sumy kosztów Tabela B dla każdego sprzedawcy. Czy ktokolwiek może pomóc? Dzięki z góry

+3

Smak RDBMS proszę? –

+0

Niestety - baza danych to MySQL –

Odpowiedz

12

Można korzystać z dwóch pod-zapytania:

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 

Albo

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

Drugie zdanie daje mi tylko wiersze z wierszy w b, nieźle z jakiegoś powodu. Pierwszy jest dokładnie tym, czego szukam i jest znacznie szybszy niż dodawanie pola sumy do mojego wyciągu. Dzięki za to. –

+0

Zmień INNER JOIN na LEFT JOIN, aby uzyskać wszystko. –

0

Wystarczy dodać , Sum(b.costs) as costsTotal do swojej listy select.

1

Jeśli jestem zrozumienia pytanie, wszystko co musisz zrobić, to dodać 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 

Moja sugestia byłoby użyć podzapytania uzyskać count i 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 

Zgaduję z pierwotnego zapytania, że ​​używasz MySQL. Sugerowałbym użycie podzapytania, ponieważ MySQL używa rozszerzenia do GROUP BY, które pozwala na nieagregowanie elementów na liście wyboru i nie jest zawarte w klauzuli GROUP BY. Może to jednak prowadzić do nieoczekiwanych rezultatów, ponieważ MySQL może wybrać zwrócone wartości. (Patrz MySQL Extensions to GROUP BY)

Z MySQL Docs:

MySQL rozszerza stosowanie GROUP BY tak, że lista wyboru może odnosić się do nonaggregated kolumn nie wymienionych w klauzuli GROUP BY. ... Możesz użyć tej funkcji, aby uzyskać lepszą wydajność, unikając niepotrzebnego sortowania i grupowania kolumn. Jest to jednak przydatne przede wszystkim wtedy, gdy wszystkie wartości w każdej niezagregowanej kolumnie nienazwanej w GROUP BY są takie same dla każdej grupy. Serwer może dowolnie wybrać dowolną wartość z każdej grupy, więc jeśli nie są one takie same, wybrane wartości są nieokreślone. Ponadto nie można wpłynąć na wybór wartości z każdej grupy poprzez dodanie klauzuli ORDER BY. Sortowanie zestawu wyników następuje po wybraniu wartości, a ORDER BY nie wpływa na wartości wybierane przez serwer.

+0

Tak, pierwsza była już moją pierwszą próbą osiągnięcia tego. Jednak nie powiodło się z powodu błędu w mojej pierwszej tabeli. Spróbowałem ponownie z twoją składnią i to działa po jakimś szukaniu błędu. Próbowałem już drugiej wersji i działa również, ale daje mi phpmyadmin "... 0 - 14 (~ 15 total, ..." co zależy od wyjaśnień.) Rozumiem, że jest to tylko rodzaj ulepszenia wydajności do użyj podkwerendy? Dzięki! –

+0

@Ole_S druga wersja wymusza prawidłowy sposób zastosowania 'GROUP BY'. Kolumny na liście select powinny być włączone w funkcję agregującą lub w' 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 tabelę podrzędną, z żądanych pól i łącząc to nie pełna tabela uczyni rzeczy easyer

wybrać. *, B.count_total, b.costs_of_table
u dealerów jako
LEFT JOIN (

SELECT aux.dealer_id, count (aux.id) jako 'count_total', suma (aux.costs) jako 'costs_of_table'
FROM zapytania AUX
GROUP BY dealer_id)

AS b ON a.id = b.dealer_id
WHERE (co chcesz)
ORDER BY nazwa ASC

przepraszam za bar pisowni jeśli