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

时间:2022-01-28 22:31:32

I have TableA in a many-to-many relationship with TableC via TableB. That is,

我通过TableB将TableA与TableC建立了多对多的关系。那是,

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

I wish the do select sum(val) on TableA, grouping by the relationship(s) to TableC. Every entry in TableA has at least one relationship with TableC. For example,

我希望在TableA上选择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

should output

75
30

since rows 1 and 3 in Table have the same relationships to TableC, but row 2 in TableA has a different relationship to TableC.

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

How can I write a SQL query for this?

如何为此编写SQL查询?

4 个解决方案

#1


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

edit Ah ha - I now see what you're getting at. Let me try again:

编辑啊哈 - 我现在看到你得到了什么。让我再尝试一次:

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

#2


1  

Hm, in MySQL it could be written like this:

嗯,在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

#3


0  

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

#4


0  

It seems that is it needed to create a key_list in orther to allow group by:

似乎需要在orther中创建一个key_list以允许group by:

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

Because GROUP_CONCAT don't exists in T-SQL:

因为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

#1


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

edit Ah ha - I now see what you're getting at. Let me try again:

编辑啊哈 - 我现在看到你得到了什么。让我再尝试一次:

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

#2


1  

Hm, in MySQL it could be written like this:

嗯,在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

#3


0  

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

#4


0  

It seems that is it needed to create a key_list in orther to allow group by:

似乎需要在orther中创建一个key_list以允许group by:

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

Because GROUP_CONCAT don't exists in T-SQL:

因为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