2016-09-23 140 views
0

我有以下SQL查詢表中的許多關係

表1

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 

表2

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

,我想查詢這樣的,我有得到以下結果

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 

基本上在結果我想通過table1.id爲total_typeX_amt添加列,在table1和table2中會有數百萬行,所以基本上尋找優化的方式來做到這一點。

+0

爲什麼做'table2'的前兩行得到他們的'amt'求和,'table2'的第三行將被轉換成另一列?爲什麼'table2'的第四行爲'total_type2_amt'導致'0'?很混亂。 – Smutje

+0

非常直的軸心,但你有什麼嘗試?爲什麼不認爲你當前的解決方案沒有優化? – qxg

+0

所有這些在哪裏?你提到該表的FK,它似乎需要創建不同的'類型'... – Gallus

回答

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 

如果你需要這個跑得快,你可以嘗試創建一個使用子查詢(我叫上面t2)的圖,在fk_table1列的索引。假設table1也有id索引,那麼聯接應該運行得相當快。

0

這不是100%你想要的結果,但你可以嘗試像

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

這應該引起類似

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

嘗試DIS獲得總計total_type1_amt

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 

輸出:

enter image description here

+0

這適用於問題中提到的特定小案例,但不可擴展。當tbl2中有兩個以上的TypeID時會發生什麼? – Gallus

0

有至少2種方式:

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 

另:

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

所以第一種方法,我不得不做所有我想要選擇的t1的顏色,在我的情況下,大約有10個這樣的顏色,這意味着我需要添加更多的顏色分組? –

+0

您的意思是10種類型?或者像'id','name'等列?如果你有很多'types' - 使用動態SQL,如果你有更多的列到GROUP BY - 只是提到他們兩次 - 在SELECT和GROUP BY部分。 – gofr1

+0

我修改了我的問題,爲table1添加了更多的顏色,所以在那種情況下,我需要添加很多組右邊的組? –

0

你可以嘗試這樣的

;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