【问题标题】:MySQL two-table INNER JOIN , LEFT JOINED onto third table with only one row with lowest valueMySQL 双表 INNER JOIN , LEFT JOINED 到第三张表,只有一行具有最低值
【发布时间】: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 我需要一些时间。数据是专有的。

标签: php mysql sql mysqli pdo


【解决方案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_orderLIMIT 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% 确定问题出在哪里,但我猜测了一下。也许我的编辑有帮助?
    • 啊哈!我已经对其进行了排序等。也就是说,它有点冗长/麻烦。我用更紧凑的解决方案编辑了我的原始帖子。
    猜你喜欢
    • 2014-10-31
    • 1970-01-01
    • 2016-11-01
    • 2011-07-14
    • 1970-01-01
    • 1970-01-01
    • 2012-09-13
    • 2015-07-18
    • 2013-01-25
    相关资源
    最近更新 更多