在多个分组上具有不同功能的 SQL 查询

Posted

技术标签:

【中文标题】在多个分组上具有不同功能的 SQL 查询【英文标题】:SQL query with different functions on multiple groupings 【发布时间】:2013-12-18 15:05:55 【问题描述】:

我正在尝试将某些已售商品的收入与这些商品的保修成本进行比较。我的代码看起来像:

SELECT DISTINCT od.orderID, pa.partID, pa.price AS revenue, wa.cost AS warcost, co.description AS wardesc
FROM orders od
LEFT OUTER JOIN parts pa ON pa.orderID = od.orderID
LEFT OUTER JOIN warranties wa ON pa.partID = wa.partID
LEFT OUTER JOIN malfunctions ml ON ml.malfID = wa.malfID
LEFT OUTER JOIN components co ON ml.compID = co.compID

返回类似下面的内容。

orderID  | partID | revenue |   warcost |   wardesc<br>
1   |   1001    | 100   |   45  |   Issue #1<br>
1   |   1001 |  100  | 50  | Issue #2<br>
1   |   1002 |  200  | 55    |  Issue #3<br>
2   |   1003 |  300  | 65    |  Issue #3<br>
2   |   1003 |  300  | 70    |  Issue #4

按顺序分组,我想对战争成本求和,但只按各个部分 ID 对收入求和,所以收入不计算两次。我发现这是不可能的!

最终结果应该如下所示,期待一些帮助!

orderID |   partID |        revenue |   warcost |   wardesc<br>
1 |     1001,1002    | 300   |  150  |  Issue #1, Issue #2, Issue #3<br>
2    |  1003     |  300  |  135  |  Issue #3, Issue #4

【问题讨论】:

这是在mysql中吗?并考虑扩展您想要进行的收入计算。 是的,这是在 mysql 中。对于收入,如果我不清楚,对不起。目标只是将每个订单中零件的收入相加 - 但在此示例中,仅使用 SUM(revenue) 会导致重复计算零件 1001 和 1003。 我添加了一个答案,如果您的结果与您执行该查询时的结果相同,请告诉我您是否仍然看到重复项 【参考方案1】:

试试这个:

SELECT od.orderID,
  GROUP_CONCAT(pa.partID) AS parts,
  SUM(pa.price) AS revenue,
  SUM(wa.cost) AS warcost,
  GROUP_CONCAT(co.description) AS wardesc
FROM orders od
LEFT OUTER JOIN parts pa ON pa.orderID = od.orderID
LEFT OUTER JOIN warranties wa ON pa.partID = wa.partID
LEFT OUTER JOIN malfunctions ml ON ml.malfID = wa.malfID
LEFT OUTER JOIN components co ON ml.compID = co.compID
GROUP BY od.orderID

sqlfiddle demo(这是对您所拥有的内容的简化,基于您的查询结果)


编辑:

获取重复值可能是因为您可能在其中一个或多个连接中有多个匹配项。如果您发现无法删除重复项并且您的原始查询具有正确的结果,您可以这样做:

SELECT orderID,
  GROUP_CONCAT(partID),
  SUM(revenue),
  SUM(warcost),
  GROUP_CONCAT(wardesc)
FROM (
  SELECT DISTINCT od.orderID AS orderID,
    pa.partID AS partID,
    pa.price AS revenue,
    wa.cost AS warcost,
    co.description AS wardesc
  FROM orders od
  LEFT OUTER JOIN parts pa ON pa.orderID = od.orderID
  LEFT OUTER JOIN warranties wa ON pa.partID = wa.partID
  LEFT OUTER JOIN malfunctions ml ON ml.malfID = wa.malfID
  LEFT OUTER JOIN components co ON ml.compID = co.compID
  ) a
GROUP BY orderID

【讨论】:

不幸的是,这样做会导致重复计算零件 1001 和 1003 的收入。它将订单 #1 的收入列为 400 美元,订单 #2 的收入列为 600 美元(而不是 300 美元和 300 美元) @MateoR。我更新了我的答案。这应该会给您预期的结果,但您可能需要一一检查这些连接,看看您是否可以找到重复的来源并尝试减轻它。 这是一次有趣的尝试,但没有运气!重复的原因是同一部件可能有多个保修问题(即重复本身不是错误)。这就是为什么在对收入求和时会重复计算第 1001 部分和第 1003 部分。这是否有点清楚? 是的。它确实:)。然后,不要直接加入保修,而是尝试加入(SELECT distinct partID FROM warranties) wa ON pa.partID = wa.PartID。在我更新答案之前,在第一个查询中尝试。如果它不起作用,我们尝试其他方法。 我必须在 pa.partID = wa.partID 上执行“左外连接(从保修中选择不同的 partID、成本、malfID)”。希望这就是您的意思,但仍然无法将收入计算两次。我担心如果我们只取不同的值,我们会丢失战争成本数据。

以上是关于在多个分组上具有不同功能的 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

带有子查询的 SQL 多个聚合函数

SQL/Impala:将多个查询(具有不同的 where 子句)合并为一个

单个查询中的多个聚合和分组

GIS SQL 查询逻辑语法

SQL Server中具有不同列数的多个查询的联合结果

SQL:查询以显示每个属性有多少用户(分组)