MySQL:以特定顺序连接两个表的不同行?

Posted

技术标签:

【中文标题】MySQL:以特定顺序连接两个表的不同行?【英文标题】:MySQL: Join distinct rows of two tables in a certain order? 【发布时间】:2015-08-29 14:18:28 【问题描述】:

我有一个我想要的库存单位和销售交易列表,(1) 按单位 SKU 加入,以及 (2) 按日期以先进先出的顺序将 ONE 交易与 ONE 库存单位相关联。我在第二部分遇到问题。

我能想到的最好的是:

SELECT `units`.`unit_date`, `units`.`unit_id`, `trans`.`tran_date`, `trans`.`tran_id`, `units`.`unit_sku` FROM `units`
    INNER JOIN `trans`
        ON `trans`.`unit_sku` = `units`.`unit_sku`
GROUP BY `trans`.`tran_id`, `trans`.`unit_sku`
ORDER BY `units`.`unit_date` asc, `trans`.`tran_date` asc
;

units表:

unit_date  | unit_id | unit_sku
2015-06-01 | 1       | U1KLM
2015-06-02 | 2       | U1KLM
2015-06-03 | 3       | U2QRS
2015-06-04 | 4       | U2QRS
2015-06-05 | 5       | U1KLM

trans表:

tran_date  | tran_id | unit_sku
2015-06-11 | A       | U2QRS
2015-06-12 | B       | U1KLM
2015-06-13 | C       | U1KLM
2015-06-14 | D       | U2QRS
2015-06-15 | E       | U1KLM

期望的结果是将tran_idunit_sku 中的一个unit_idunit_date 从最早到最新的顺序连接起来:

unit_date  | unit_id | tran_date  | tran_id | unit_sku
2015-06-01 | 1       | 2015-06-12 | B       | U1KLM
2015-06-02 | 2       | 2015-06-13 | C       | U1KLM
2015-06-03 | 3       | 2015-06-11 | A       | U2QRS
2015-06-04 | 4       | 2015-06-14 | D       | U2QRS
2015-06-05 | 5       | 2015-06-15 | E       | U1KLM

查询(不需要的)结果仅将tran_id 连接到unit_sku 最早出现的unit_id

unit_date  | unit_id | tran_date  | tran_id | unit_sku
2015-06-01 | 1       | 2015-06-12 | B       | U1KLM
2015-06-01 | 1       | 2015-06-13 | C       | U1KLM
2015-06-01 | 1       | 2015-06-15 | E       | U1KLM
2015-06-03 | 3       | 2015-06-11 | A       | U2QRS
2015-06-03 | 3       | 2015-06-14 | D       | U2QRS

关于如何获得所需结果的任何想法?在这个设置中,只有unit_datetran_date 是可排序的;其余的都是随机生成的。

复制脚本:

DROP TEMPORARY TABLE IF EXISTS `units`;
DROP TEMPORARY TABLE IF EXISTS `trans`;
CREATE TEMPORARY TABLE `units` (`unit_date` date, `unit_id` char(1) , `unit_sku` char(5), PRIMARY KEY(`unit_id`));
CREATE TEMPORARY TABLE `trans` (`tran_date` date, `tran_id` char(1) , `unit_sku` char(5), PRIMARY KEY(`tran_id`));

INSERT INTO `units` (`unit_date`, `unit_id`, `unit_sku`) VALUES
    ('2015-06-01', '1', 'U1KLM')
    , ('2015-06-02', '2', 'U1KLM')
    , ('2015-06-03', '3', 'U2QRS')
    , ('2015-06-04', '4', 'U2QRS')
    , ('2015-06-05', '5', 'U1KLM')
;

INSERT INTO `trans` (`tran_date`, `tran_id`, `unit_sku`) VALUES
    ('2015-06-11', 'A', 'U2QRS')
    , ('2015-06-12', 'B', 'U1KLM')
    , ('2015-06-13', 'C', 'U1KLM')
    , ('2015-06-14', 'D', 'U2QRS')
    , ('2015-06-15', 'E', 'U1KLM')
;

SELECT `units`.`unit_date`, `units`.`unit_id`, `trans`.`tran_date`, `trans`.`tran_id`, `units`.`unit_sku` FROM `units`
    INNER JOIN `trans`
        ON `trans`.`unit_sku` = `units`.`unit_sku`
GROUP BY `trans`.`tran_id`, `trans`.`unit_sku`
ORDER BY `units`.`unit_date` asc, `trans`.`tran_date` asc
;

【问题讨论】:

你能保证这两个表中始终存在1对1的记录关系吗?另外,您使用的是什么数据库? 一个单元可以有多个交易——例如,如果一个单元被退回然后第二次出售。但最常见的是一对一。关于什么数据库,我在 mysql 5.6.24 上使用本地解决方案,如果这就是你的意思吗? 【参考方案1】:

我相信这就是您要寻找的:(这是假设一对一的关系)

SET @UNITRN := 0;
SET @TRANSRN :=0;
SELECT A.`unit_date`, A.`unit_id`, B.`tran_date`, B.`tran_id`, A.`unit_sku` FROM (SELECT @UNITRN := @UNITRN + 1 AS ROWNUM, UNIT_DATE, UNIT_ID, UNIT_SKU FROM UNITS ORDER BY UNIT_SKU, UNIT_DATE ASC) A
JOIN (SELECT @TRANSRN := @TRANSRN + 1 AS ROWNUM, TRAN_DATE, TRAN_ID, UNIT_SKU FROM TRANS ORDER BY UNIT_SKU, TRAN_DATE ASC) B
ON A.UNIT_SKU = B.UNIT_SKU
AND A.ROWNUM = B.ROWNUM
ORDER BY A.UNIT_DATE ASC

【讨论】:

是的,这适用于一对一。我正在玩投掷 1 对 n 的游戏。我需要看看我的数据是如何连接的,但这让我开始了。

以上是关于MySQL:以特定顺序连接两个表的不同行?的主要内容,如果未能解决你的问题,请参考以下文章

连接两个表以匹配整数以获取用户名

VBNET如何在两个表的不同行中插入多个值

以特定顺序从两个表 mysql 中选择,因为输出必须具有特定结构

在 MySQL 中为 perfromant 连接的两个属性键入唯一表的最佳方法?

如何计算两个多对多字段上的不同行

Python Pandas - 连接两个具有不同行数和列数的数据框