MySQL 双表 INNER JOIN , LEFT JOINED 到第三张表,只有一行具有最低值
Posted
技术标签:
【中文标题】MySQL 双表 INNER JOIN , LEFT JOINED 到第三张表,只有一行具有最低值【英文标题】:MySQL two-table INNER JOIN , LEFT JOINED onto third table with only one row with lowest value 【发布时间】:2019-02-23 00:37:23 【问题描述】:我四处搜索,找到了我正在寻找的 near example,但它在我的情况下不起作用。
我有一个查询,它在两个表上执行 INNER JOIN,这个连接极大地限制了我的整个数据集。然后我想 LEFT JOIN 到第三个表中,但我只想要第三个表中的一条记录。左连接的原因是因为并非 INNER JOIN 的每个结果在第三张表中都有匹配项。像这样的:
SELECT DISTINCT t1.code, t2.id, t2.code, t3.id, t3.source_title, t3.display_order
FROM table1 t1
INNER JOIN table2 t2 ON t2.code=t1.code AND t2.type=0
LEFT JOIN table3 t3 ON t3.code=t1.code
ORDER BY t1.code, t3.display_order
此查询返回的记录过多,因为第三个表包含多个具有匹配代码的记录。我只想要第一个与最低 display_order 值匹配的记录,不幸的是,我无法将记录限制为 display_order=1,因为最低显示顺序并不总是一个。
重要提示:此查询返回的 t3.id 值(如果有)必须与 display_order 值最低的记录相对应。也就是说,它不起作用如果查询正确返回了最低的 display_order 值,但 t3.id 值对应于表 3 中的其他记录。
这甚至可能吗?任何帮助将不胜感激。
编辑:根据尼克的建议,我已经尝试过了,这似乎有效。我会做一些验证并报告:
SELECT DISTINCT t1.code, t2.*, sq.id, sq.source_title, sq.display_order
FROM table1 t1
INNER JOIN table2 p ON t2.code=t1.code AND t2.type=0
LEFT JOIN (
SELECT t3.*
FROM table3 t3
WHERE t3.display_order=(
SELECT MIN(display_order)
FROM table3 t3a
WHERE t3a.code = t3.code
)
) sq ON sq.code=t1.code
ORDER BY t1.code, sq.display_order
【问题讨论】:
您能提供一些示例数据并期待结果吗? @D-Shih 我需要一些时间。数据是专有的。 【参考方案1】:您应该可以将LEFT JOIN
中的table3
替换为
(SELECT *
FROM table3 t3
WHERE display_order = (SELECT MIN(display_order)
FROM table3 t3a
WHERE t3a.code = t3.code)
) t3
【讨论】:
【参考方案2】:在 mysql 8.0 中,您可以尝试对每个代码使用 row_number()
,并在来自 table3
的子查询中按 display_order
排序。然后左加入该结果并检查 row_number()
是否等于 1。
SELECT DISTINCT
t1.code,
t2.id,
t2.code,
t3.id,
t3.source_title,
t3.display_order
FROM table1 t1
INNER JOIN table2 t2
ON t2.code = t1.code
LEFT JOIN (SELECT t3.id,
t3.source_title,
t3.display_order,
t3.code,
row_number() OVER (PARTITION BY t3.code
ORDER BY t3.display_order) rn
FROM table3 t3) t3
ON t3.code = t1.code
WHERE t2.type = 0
AND t3.rn = 1
ORDER BY t1.code,
t3.display_order;
在较低版本中,您可以尝试按display_order
和LIMIT 1
排序的相关子查询(仅获取一条记录)。
SELECT DISTINCT
t1.code,
t2.id,
t2.code,
(SELECT t3.id
FROM table3 t3
WHERE t3.code = t1.code
ORDER BY t3.display_order,
t3.id
LIMIT 1) id,
(SELECT t3.source_title
FROM table3 t3
WHERE t3.code = t1.code
ORDER BY t3.display_order,
t3.id
LIMIT 1) source_title,
(SELECT t3.display_order
FROM table3 t3
WHERE t3.code = t1.code
ORDER BY t3.display_order,
t3.id
LIMIT 1) display_order
FROM table1 t1
INNER JOIN table2 t2
ON t2.code = t1.code
WHERE t2.type = 0
ORDER BY t1.code,
(SELECT t3.display_order
FROM table3 t3
WHERE t3.code = t1.code
ORDER BY t3.display_order,
t3.id
LIMIT 1);
我假设,table3
中的 display_order
不是唯一的,但 id
是唯一的。所以我在子查询中的ORDER BY
子句中添加了id
,以确保在每个子查询中选择相同的记录。如果display_order
是唯一的,您可以从ORDER BY
子句中删除id
。
编辑:
如果您不想重复(整体)ORDER BY
子句中的子查询,您也可以按列序号排序。例如:
...
ORDER BY 1, 6;
【讨论】:
我的工作站(我计划很快升级)有一个更旧的版本,5.6.33。我会看看我是否可以让这个其他查询工作——虽然这很冗长。 我想说的是,您拥有的第二个产品(这是一件艺术品)确实提供了我所追求的确切数据集,但我似乎无法使用它(例如,更改整体排序顺序)。 @S.Imp:不是 100% 确定问题出在哪里,但我猜测了一下。也许我的编辑有帮助? 啊哈!我已经对其进行了排序等。也就是说,它有点冗长/麻烦。我用更紧凑的解决方案编辑了我的原始帖子。以上是关于MySQL 双表 INNER JOIN , LEFT JOINED 到第三张表,只有一行具有最低值的主要内容,如果未能解决你的问题,请参考以下文章
mysql 里面JOIN 和 INNER JOIN 区别是啥
MySQL中inner join 和 cross join 的区别
MySQL left join right join inner join