具有一对多关系的SQL查询

时间:2016-09-23 07:41:34

标签: sql sql-server

我有下表

表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 

基本上在结果​​中我希望group1.id为group_id添加了total_typeX_amt的列,table1和table2中将有数百万行,所以基本上寻找优化的方法来实现它。

6 个答案:

答案 0 :(得分: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列上添加索引。假设table1id上也有一个索引,那么连接应该运行得相当快。

答案 1 :(得分: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  

答案 2 :(得分: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

答案 3 :(得分: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

答案 4 :(得分:0)

至少有两种方式:

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

答案 5 :(得分: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