【问题标题】:Join 2 tables on dynamically changing column在动态变化的列上加入 2 个表
【发布时间】:2018-04-08 23:33:31
【问题描述】:

拥有这 2 个表格(来自库存功能)

SQL Fiddle

-- ins table
+------+-------------+-------------+
| id   |  direction  |   quantity  |
+------+-------------+-------------+
|  1   |     in      |      5      |
|  2   |     in      |      3      |
+------+-------------+-------------+


-- outs table
+------+-------------+-------------+
| id   |  direction  |   quantity  |
+------+-------------+-------------+
|  1   |     out     |      4      |
|  2   |     out     |      1      |
|  3   |     out     |      2      |
|  4   |     out     |      1      |
+------+-------------+-------------+

如何将 outs 表中的行连接到 ins 表中数量覆盖/等于加入它的 outs 行的数量的行,换句话说 如何获得这样的结果?

-- result
+------+-------------+-------------+------+-------------+-------------+
| id   |  direction  |   quantity  |  id  |  direction  | quantity    |
+------+-------------+-------------+------+-------------+-------------+
|  1   |     out     |      4      |  1   |     in      |      5      |
|  2   |     out     |      1      |  1   |     in      |      5      |
|  3   |     out     |      2      |  2   |     in      |      3      |
|  4   |     out     |      1      |  2   |     in      |      3      |
+------+-------------+-------------+------+-------------+-------------+

如您所见,outs 表的第 1,2 行取自/连接到ins 表的第 1 行,outs 表的第 3,4 行取自/连接到 @987654331 的第 2 行@表

注意:保证 2 个表中的数量是密封的(ins 表中的一行始终具有完全等于表 @987654333 中的 1 个或多个行的数量@)

我希望我能做这样的事情

-- sedu SQL
SELECT 
    whatever 
FROM 
    outs left join 
    ins on outs.quantity <= (ins.quantity - previously joined outs.quantities);

【问题讨论】:

  • 你运行的是什么版本? MariaDB 10.1(?) 和 MySQL 8.0 中提供了“窗口化”函数(用于累积总和)。
  • @RickJames 是 5.6.38,但我已准备好更新任何内容,以便我的应用程序可以扩展
  • @RickJames 如果你有时间,能否请你检查一下this question 关于你不规范化连续数据的规则?

标签: mysql sql


【解决方案1】:

由于几个原因,在 MySQL 中这样做很痛苦。首先,MySQL 对累积和的支持不是很好,这是您要比较的。

其次,您的结果集有点弱。显示所有对每个outs 记录有贡献的ins 记录更有意义,而不仅仅是其中一个。

为此,您可以对累积和使用连接,如下所示:

select o.*, (o.to_quantity  - o.quantity) as from_quantity,
       i.*
from (select o.*,
             (select sum(o2.quantity)
              from outs o2
              where o2.id <= o.id
             ) as to_quantity
      from outs o
     ) o join
     (select i.*,
             (select sum(i2.quantity)
              from ins i2
              where i2.id <= i.id
             ) as to_quantity
      from ins i
     ) i
     on (o.to_quantity  - o.quantity) < i.to_quantity and
        o.to_quantity > (i.to_quantity  - i.quantity)

Here 是 SQL Fiddle。

【讨论】:

  • 非常感谢 Gordon 先生在 SO 社区中为我们提供的大量帮助、经验、想法和聪明的思维方式。
  • 关于我的结果集的重要说明,数据库中数量的数据保证为1个或多个out行始终取自仅1 @ 987654327@ 行(no 许多ins 贡献于 1 个out),因为我将使用此查询来计算Cost of goods sold,因此该查询回答了“哪个in 行将是取自每个out 行?”
【解决方案2】:

子查询相关方法也可能有用

select t.id, t.direction, t.quantity, i.id, i.direction, i.quantity  
from (
      select id, direction, quantity, 
             quantity + coalesce((select quantity from outs where id < o.id order by id desc limit 1),
                      (select quantity from outs where id > o.id order by id limit 1)) Qty
      from outs o
)t inner join ins i on i.quantity = t.Qty

【讨论】:

  • 非常感谢您的时间和帮助,感谢您的帮助,但我认为您的解决方案已针对问题中的示例数据集进行了调整,因为它累积了前 1 个 @987654323 的数量@ 行和it will not work if the data-set is changed。感谢您介绍coalesce 功能,因为我以前不知道它。
猜你喜欢
  • 1970-01-01
  • 2018-02-13
  • 1970-01-01
  • 1970-01-01
  • 2020-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多