SQL запрос агрегации, группировка по записям в соединительной таблице - PullRequest
1 голос
/ 21 ноября 2011

У меня есть TableA в отношениях «многие ко многим» с TableC через TableB.То есть,

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

Я хочу сделать do select sum(val) в Таблице A, сгруппировав по отношению (ям) к 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, но строка 2 в TableA имеет другое отношение к TableC.

Как мне написать SQL-запрос для этого?

Ответы [ 4 ]

1 голос
/ 21 ноября 2011

Хм, в 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
1 голос
/ 21 ноября 2011
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 Ага - теперь я вижу, к чему вы клоните.Позвольте мне попробовать еще раз:

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
0 голосов
/ 21 ноября 2011

Кажется, что необходимо создать список ключей в другом, чтобы разрешить группировку:

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

Поскольку GROUP_CONCAT не существует в T-SQL:

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
0 голосов
/ 21 ноября 2011
SELECT sum(a.val) 
FROM  tablea a
INNER JOIN tableb b ON (b.fKeyA = a.id)
GROUP BY b.fKeyC
...