SQL聚合查询,按联结表中的条目分组

时间:2011-11-21 17:43:07

标签: sql sql-server sql-server-2008 many-to-many aggregate-functions

我通过TableB将TableA与TableC建立多对多关系。也就是说,

TableA       TableB           TableC
id | val     fkeyA | fkeyC    id | data

我希望在TableA上做select sum(val),按照与TableC的关系进行分组。 TableA中的每个条目与TableC至少有一个关系。例如,

TableA
1 | 25
2 | 30
3 | 50

TableB
1 | 1
1 | 2
2 | 1
2 | 2
2 | 3
3 | 1
3 | 2

应输出

75
30

因为表中的第1行和第3行与TableC具有相同的关系,但TableA中的第2行与TableC具有不同的关系。

如何为此编写SQL查询?

4 个答案:

答案 0 :(得分:1)

SELECT    
   sum(tableA.val) as sumVal,    
   tableC.data  
FROM    
   tableA 
     inner join tableB ON tableA.id = tableB.fkeyA 
     INNER JOIN tableC ON tableB.fkeyC = tableC.id  
GROUP by tableC.data

修改的 啊哈 - 我现在看到你得到了什么。让我再试一次:

SELECT
   sum(val) as sumVal,
   tableCGroup
FROM
(

SELECT 
   tableA.val,
   (
      SELECT cast(tableB.fkeyC as varchar) + ',' 
      FROM tableB WHERE tableB.fKeyA = tableA.id
      ORDER BY tableB.fkeyC
      FOR XML PATH('') 
   ) as tableCGroup
FROM
   tableA


) tmp
GROUP BY
    tableCGroup

答案 1 :(得分:1)

嗯,在MySQL中它可以这样编写:

SELECT
    SUM(val) AS sumVal
FROM
    ( SELECT
          fkeyA
        , GROUP_CONCAT(fkeyC ORDER BY fkeyC) AS grpC
      FROM 
          TableB
      GROUP BY
          fkeyA
    ) AS g
  JOIN
    TableA a
      ON a.id = g.fkeyA
GROUP BY 
    grpC

答案 2 :(得分:0)

SELECT sum(a.val) 
FROM  tablea a
INNER JOIN tableb b ON (b.fKeyA = a.id)
GROUP BY b.fKeyC

答案 3 :(得分:0)

似乎需要创建一个密钥列表才能允许分组:

75 -> key list = "1 2"
30 -> key list = "1 2 3"

因为T-SQL中不存在GROUP_CONCAT:

WITH CTE ( Id, key_list )
          AS ( SELECT TableA.id, CAST( '' AS VARCHAR(8000) )
                 FROM TableA 
                GROUP BY TableA.id
                UNION ALL
               SELECT TableA.id, CAST( key_list + ' ' + str(TableB.id) AS VARCHAR(8000) )
                 FROM CTE c
                INNER JOIN TableA A
                   ON c.Id = A.id
                INNER join TableB B
                   ON B.Id = A.id
                WHERE A.id > c.id      --avoid infinite loop
              )
Select
   sum( val )
from 
   TableA inner join
   CTE on (tableA.id = CTE.id)
group by
   CTE.key_list