【问题标题】:SQL joins without duplicate parent rows没有重复父行的 SQL 连接
【发布时间】:2012-03-17 17:23:02
【问题描述】:

我在一个 x 对多个 y 的 SQL Server 数据库中有一对多的关系。

当我加入这两个表时,我会得到如下数据:

1x 1x 1y 1y
1x 1x 2y 2y

我两次获取 x 数据,因为有两个子行与之关联。

问题是我需要对两个表中的列进行求和,并且在每种情况下我只想对每个唯一行列求和一次。因此我想要这样的数据:

1x   1x   1y 1y
null null 2y 2y

我知道这可以通过子查询很容易地完成,但涉及到性能方面的考虑。

谢谢。

编辑 -

因为每个人都想要一个更具体的例子:

有一张非常大的订单表,上面有某家商店的订单。 这些订单可以有折扣。折扣可以应用于多个订单。 每个订单在顶层都有一个税金、运费和折扣总计列。 每个订单都有一组子订单项。这些订单商品具有商品价格和销售数量。

对于每个折扣,我想要总销售额。 这将是每个订单加上折扣税的总和 + 每个订单加上每个折扣运费的总和 + 每个订单订单商品价格的总和 * 数量 - 折扣总额的总和。

所以我有两个需要相加的级别。订单上的和订单商品上的。

无法修改表格。

我通过子查询得到了正确的数字,但我还必须对总和列进行排序,我发现它非常慢。

我当前的模型按应用的折扣分组并加入订单和订单项目。它非常有效,但会返回具有超过 1 个子级的订单列的重复项。

【问题讨论】:

  • 不知道其他 DBMS,但 MySQL 支持COUNT(DISTINCT somefield),所以你不算骗子。
  • 如果您需要在没有任何其他约束的情况下对这些列进行求和,为什么要在一个查询中将它们连接在一起?如果有进一步的限制,请将它们添加到问题中。
  • 我认为你错过了重点(或者我可能是)。如果我们有一个或两个具体的例子(包括样本数据和预期结果),我们或许可以提出解决方案;连接本身并不能提供性能提升/速度提升。
  • "示例数据和预期结果" - 您仍然在高层次上描述事物,而给出一组表定义、插入语句和预期结果将允许使用构建实际查询(即使表名需要修改)并根据预期结果验证它们。扩展的叙述对(我)没有帮助。
  • 另外,如果您有一个现有的慢查询,也请发布它 - 我们也许可以在对数据库知之甚少的情况下将其转换为更好的查询。

标签: sql join


【解决方案1】:

如果子查询可以返回想要的结果,你应该使用它。

这始终取决于您的数据库结构和要求。子查询并不总是需要增加开销。

【讨论】:

    【解决方案2】:

    简单地说,您想计算每个订单的总成本,然后将按折扣分组的所有订单的总成本相加。

    with orderTotals as (
    select discountID,
           min(tax + shipping - discount) + sum(price * quantity) as total
      from orders
      join items on orders.orderID = items.orderID
     group by discountID, orders.orderID
    )
    select discountID,
           sum(total) as total
      from orderTotals
     group by discountID
    ;
    

    您可以用 max() 或 avg() 代替 min() 并仍然得到相同的结果,因为税金、运费和折扣对于给定订单是一个常数。

    【讨论】:

    • 我想知道为什么你没有在group by 中包含taxshippingdiscount。此外,group by 中的 orderID 必须与两个表别名中的任何一个一起指定。 (实际上,为了清楚起见,我会将相应的表名添加到 CTE 中的每个列名中。)
    • 您对 group by(固定)中的 orderID 是绝对正确的,并且将表名添加到每一列绝不是一个坏主意。不知道在 group by 中包含税费、运费和折扣可能更有效。
    猜你喜欢
    • 2013-07-29
    • 1970-01-01
    • 1970-01-01
    • 2017-08-22
    • 1970-01-01
    • 2022-01-02
    • 2013-10-07
    • 1970-01-01
    • 2013-08-02
    相关资源
    最近更新 更多