1

我有TableA與TableC通過TableB與TableC存在多對多關係。也就是說,SQL聚合查詢,按結點表中的條目分組

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

我希望做select sum(val) TableA上,通過關係(一個或多個)以表C分組。 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具有以表C相同的關係,但第2行TableA中具有表C不同的關係。

如何爲此編寫SQL查詢?

+0

因此,如果第4行在表A中輸入的值爲30,並且通過記錄1和2也與C相關,那麼75會變成105?如果第5條記錄的輸入值爲30,並且通過記錄6和7與c相關,您會在結果中看到75,30,30? – xQbert

+0

@xQert:是和是 – cm007

回答

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 
+0

此查詢將在我的示例中包含來自TableA的第2行,給出105. – cm007

+0

查看tableC的內容以及您的意思是「TableA中的第2行與TableC具有不同的關係「 –

+0

忽視該請求 - 我沒有看到 –

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

之前的完整問題此查詢將包括TableA中的row2(在我的示例中爲105. – cm007

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 
+0

+1),您似乎已經正確解碼了OP的意圖。 – Johan

+0

我相信在SQL Server中,您可以使用FOR XML PATH('')完成相同的事情;我已經更新了我的答案,以顯示如何工作。 –

0

似乎是它需要建立在orther一個KEY_LIST允許GROUP BY:

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

這似乎給了無限遞歸,我無法弄清楚如何讓它變得有限。 – cm007

+2

現在拍攝,007。 – danihp