每个subcat FROM子查询AS列的SELECT总和

时间:2018-05-26 17:59:59

标签: mysql group-by

给出3个表(合同,服务,合同_服务)

作为多种服务的合同以4种类型组织(现在,将会有更多)。

我需要的是获得所有价格的SUM()GROUP BY service_type FOR EACH Contract,每份合约一行。

contracts.id, 'total_service_type_1', 'total_service_type_2', 'total_service_type_3', 'total_service_type_4'

合同

  • ID

服务

  • ID
  • servicetype_id

Contracts_Services

  • contract_id
  • 的service_id

这是我到目前为止所得到的

SELECT c.id,s.servicetype_id,sum(cs.price)as total
FROM contracts c
LEFT JOIN addresses a ON a.id = c.address_id
LEFT JOIN contracts_services cs ON cs.contract_id = c.id
LEFT JOIN services s ON s.id = cs.service_id
WHERE s.servicetype_id IS NOT NULL
GROUP BY c.id,s.servicetype_id
ORDER BY c.id

如何将这些查询结果转换为单个合约行的列?

1 个答案:

答案 0 :(得分:1)

你不能在MySQL(或任何SQL风格)中拥有动态列。因此,您只能通过将每个服务类型添加为查询的新join来实现此目的。为简洁起见,我在下面的示例中添加了两种服务类型,对于额外的服务类型,只需添加更多LEFT JOIN

最后说:有你的痛苦。这个解决方案绝对不灵活。对于您添加的每种新服务类型,您必须再次编辑查询。您应该在编程语言中寻找解决方案。因此,当您从MySQL调用PHP时,请使用您已有的查询并且工作得非常好,并使用PHP重写您的数组(动态),以便获得所需的输出(用你正在使用的编程语言替换PHP

SELECT 
  c.id AS contractId, 
  SUM(cs1.price) AS service1Total,
  SUM(cs2.price) AS service2Total
FROM contracts c
JOIN services s
LEFT JOIN contracts_services cs1 ON 
  cs1.contract_id = c.id 
  AND cs1.service_id = s.id
  AND s.servicetype_id = 1
LEFT JOIN contracts_services cs2 ON 
  cs2.contract_id = c.id 
  AND cs2.service_id = s.id
  AND s.servicetype_id = 2
GROUP BY c.id

SQLFiddle:http://sqlfiddle.com/#!9/4f9a9c/2/0

注意:如果您希望SUM(cs1.price)超过IFNULL(SUM(cs1.price), 0),则可以将0替换为NULL

编辑:替代查询,在阅读Paul Spiegel的评论(关于数据透视表)后,连接较少,因此更有可能对您的数据库服务器友好。但是,与上述查询具有相同的缺点:每次添加新服务类型时都必须对其进行编辑。

SELECT 
  c.id AS contractId, 
  SUM(IF(s.servicetype_id = 1, cs.price, 0)) AS service1Total,
  SUM(IF(s.servicetype_id = 2, cs.price, 0)) AS service2Total
FROM contracts c
LEFT JOIN contracts_services cs ON cs.contract_id = c.id 
LEFT JOIN services s ON cs.service_id = s.id
GROUP BY c.id