2016-09-23 6 views
0

Ich habe folgende TabelleSQL-Abfrage mit einem zu vielen Beziehung

Table1

id name col1 col2 col3 col4 
----------------------------------- 
1 test 1.1 1.2 1.3  1.4 
2 test2 2.1 2.2 2.3  2.4 

Table2

id fk_table1 amt type(fk_table3) 
----------------------------------- 
1  1   2  1 
2  1   3  1 
3  1   9  2 
4  2   1  1 

und ich möchte so abfragen, dass ich zu bekommen habe unten führen

id | name | total_type1_amt |total_type2_amt | col1 col2 col3 col4 
----------------------------------------------------------------------- 
1 test  5 (2+3)   9     1.1 1.2 1.3 1.4 
2 test2  1    0     2.1 2.2 2.3 2.4 

Grundsätzlich im Ergebnis Ich will eine group by table1.id mit addierten Spalten für total_typeX_amt, es wird Millionen von Zeilen in table1 und table2 geben, also grundsätzlich nach optimierten Möglichkeiten suchen.

+0

Warum Werden die ersten beiden Zeilen von 'table2' 'summiert und die dritte Zeile von' table2' wird in eine andere Spalte transformiert? Und warum führt die vierte Zeile von 'table2' zu '0' für' total_type2_amt'? Sehr verwirrend. – Smutje

+0

Sehr gerade Pivot, aber was hast du probiert? Warum denken Sie nicht, dass Ihre aktuelle Lösung nicht optimiert ist? – qxg

+0

Wo ist table3 in all dem? Sie erwähnen eine FK für diese Tabelle, und es scheint, dass Sie die verschiedenen "Typen" erstellen müssen ... – Gallus

Antwort

0
SELECT t1.id, 
     t1.name, 
     t2.total_type1_amt, 
     t2.total_type2_amt 
FROM table1 t1 
INNER JOIN 
(
    SELECT fk_table1, 
      SUM(CASE WHEN type = 1 THEN amt END) AS total_type1_amt, 
      SUM(CASE WHEN type = 2 THEN amt END) AS total_type2_amt 
    GROUP BY fk_table1 
) t2 
    ON t1.id = t2.fk_table1 

Wenn Sie diese benötigen, schnell zu laufen, können Sie versuchen, eine Ansicht erstellen, die Unterabfrage (die ich t2 oben genannt), mit einem Index auf der fk_table1 Spalte. Unter der Annahme, dass table1 auch einen Index auf id hat, sollte der Join relativ schnell ausgeführt werden.

0

Es ist nicht zu 100% das gewünschte Ergebnis, aber man könnte so etwas wie

select fk_table1, type, sum(amt) 
from table1 
inner join table2 on table1.id = table2.fk_table1 
group by fk_table1, type 

versuchen, die so etwas wie

fk_table1 | type | sum 
1   1  5 
1   2  9 
2   1  1 
0

versuchen dis zu erhalten insgesamt für total_type1_amt führen sollte

select table1.id, table2.name ,(select count(table2.amt) as total_type1_amt where table1.id = table2.fk_table1 from table.1) from table1 
    inner join table2 on table1.id = table2.fk_table1 
    group by table.id 
0
SELECT 
    T1.id, 
    T1.name, 
    SUM(CASE T2.type WHEN 1 THEN T2.amt ELSE 0 END) AS total_type1_amt, 
    SUM(CASE T2.type WHEN 2 THEN T2.amt ELSE 0 END) AS total_type2_amt 
FROM @tbl1 T1 
LEFT JOIN @tbl2 T2 ON T1.id=T2.fk_table1 
GROUP BY T1.id,T1.name 

Ausgang:

enter image description here

+0

Dies funktioniert in dem spezifischen kleinen Fall, der in der Frage erwähnt wird, ist aber nicht skalierbar. Was passiert, wenn in tbl2 mehr als 2 TypeIDs vorhanden sind? – Gallus

0

Es mindestens 2 Möglichkeiten:

SELECT t1.id, 
     t1.name, 
     COALESCE(SUM(CASE WHEN [type] = 1 THEN amt END),0) AS total_type1_amt, 
     COALESCE(SUM(CASE WHEN [type] = 2 THEN amt END),0) AS total_type2_amt, 
     col1, 
     col2, 
     col3, 
     col4 
FROM table1 t1 
LEFT JOIN table2 t2 
    ON t1.id = t2.fk_table1 
GROUP BY t1.id, t1.name, col1, col2, col3, col4 

Ein anderer:

SELECT * 
FROM ( 
SELECT t1.id, 
     t1.name, 
     t2.[type], 
     SUM(t2.amt) as sum 
FROM table1 t1 
LEFT JOIN table2 t2 
    ON t1.id = t2.fk_table1 
GROUP BY t1.id, t1.name, t2.[type] 
) as t 
PIVOT (
    MAX(sum) FOR type IN ([1],[2]) 
) as pvt 
+0

Also musste ich mit dem ersten Ansatz eine Gruppe nach allen Farben von t1 machen, die ich auswählen wollte, in meinem Fall gibt es etwa 10 solcher Farben, also bedeutet das, dass ich mehr Farben hinzufügen muss um sie zu gruppieren? –

+0

10 Arten meinen Sie? Oder Spalten wie "ID", "Name" usw.? Wenn Sie viele 'Typen' haben - verwenden Sie dynamisches SQL, wenn Sie mehr Spalten zu GROUP BY haben - nur zweimal erwähnt - in SELECT- und GROUP BY-Teilen. – gofr1

+0

Ich änderte meine Frage, fügte Tabelle1 weitere Kolumnen hinzu, also musste ich in diesem Fall so viele Gruppen hinzufügen, oder? –

0

Sie können wie versuchen diese

;WITH cte 
AS (SELECT 
    fk_table1, SUM([1]) total_type1_amt, COALESCE(SUM([2]), 0) total_type2_amt 
FROM #table1 PIVOT (MAX(amt) FOR type IN ([1], [2])) p 
GROUP BY fk_table1) 
SELECT 
    t.id, t.name, c.total_type1_amt, c.total_type2_amt 
FROM #table1 t 
LEFT JOIN cte c 
    ON t.id = c.fk_table1 
Verwandte Themen