mysql - 连接几个表的 SQL 查询 (MySQL)

标签 mysql sql select group-by left-join

我在 SQL 查询 (MySQL) 方面需要“一点”帮助。

我有以下表格:

COURIERS 表:

    +------------+
    | COURIER_ID |
    +------------+

DELIVERIES 表:

    +-------------+------------+------------+
    | DELIVERY_ID | COURIER_ID | START_DATE |
    +-------------+------------+------------+

ORDERS 表:

    +----------+-------------+-------------+
    | ORDER_ID | DELIVERY_ID | FINISH_DATE |
    +----------+-------------+-------------+

COORDINATES 表:

    +-------------+-----+-----+------+
    | DELIVERY_ID | LAT | LNG | DATE |
    +-------------+-----+-----+------+

在真实的数据库中,我在每个表中有更多的列,但对于这个例子,上面的列就足够了。

我需要什么?

  • 返回所有 express 员 [COURIER_ID] 的 SQL 查询,他们的最后 交货 [DELIVERY_ID](基于上次 START_DATE), 交货的最后坐标 [LATLNG](基于最后的 DATE)和剩余订单数(最后交货的订单总数没有 FINISH_DATE)。

  • express 员可以不送货,在这种情况下我想要 DELIVERY_ID = NULL,LAT = NULL 和 LNG = 结果中的 NULL。

  • 交货可以没有坐标,在这种情况下我希望 LAT = NULL 结果中的 LNG = NULL。

我能做什么?

SELECT c.`COURIER_ID`,
       d.`DELIVERY_ID`,
       r.`LAT`,
       r.`LNG`,
  (SELECT COUNT(DISTINCT `ORDER_ID`)
   FROM `ORDERS`
   WHERE `DELIVERY_ID` = d.`DELIVERY_ID`
     AND `FINISH_DATE` IS NULL) AS REMAINING_ORDERS

FROM `COURIERS` AS c
LEFT JOIN `DELIVERIES` AS d USING (`COURIER_ID`)
LEFT JOIN `COORDINATES` AS r ON r.`DELIVERY_ID` = d.`DELIVERY_ID`

WHERE (CASE WHEN
         (SELECT MAX(`START_DATE`)
          FROM `DELIVERIES`
          WHERE `COURIER_ID` = c.`COURIER_ID`) IS NULL THEN d.`START_DATE` IS NULL ELSE d.`START_DATE` =
         (SELECT MAX(`START_DATE`)
          FROM `DELIVERIES`
          WHERE `COURIER_ID` = c.`COURIER_ID`) END)
  AND (CASE WHEN
         (SELECT MAX(`DATE`)
          FROM `COORDINATES`
          WHERE `DELIVERY_ID` = d.`DELIVERY_ID`) IS NULL THEN r.`DATE` IS NULL ELSE r.`DATE` =
         (SELECT MAX(`DATE`)
          FROM `COORDINATES`
          WHERE `DELIVERY_ID` = d.`DELIVERY_ID`) END)
GROUP BY c.`COURIER_ID`
ORDER BY d.`START_DATE` DESC

问题是,当我有超过 5k 个 COORDINATES 时,这个查询非常慢(从 5 秒到 20 秒),而且有时它不会返回所有信使。

非常感谢您提供任何解决方案。

最佳答案

试试这个:

SELECT C.COURIER_ID, D.DELIVERY_ID, D.START_DATE, D.FINISH_DATE, 
       B.LAT, B.LNG, B.DATE, C.NoOfOrders
FROM COURIERS C 
LEFT JOIN ( SELECT * 
            FROM (SELECT * 
                  FROM DELIVERIES D 
                  ORDER BY D.COURIER_ID, D.START_DATE DESC
                ) A 
            GROUP BY COURIER_ID
          ) AS A ON C.COURIER_ID = A.COURIER_ID 
LEFT JOIN ( SELECT * 
            FROM (SELECT * 
                  FROM COORDINATES CO 
                  ORDER BY CO.DELIVERY_ID, CO.DATE DESC
                ) B
            GROUP BY CO.DELIVERY_ID
          ) AS B ON A.DELIVERY_ID = B.DELIVERY_ID 
LEFT JOIN ( SELECT O.DELIVERY_ID, COUNT(1) NoOfOrders
            FROM ORDERS O WHERE FINISH_DATE IS NULL
            GROUP BY O.DELIVERY_ID
          ) AS C ON A.DELIVERY_ID = C.DELIVERY_ID;

关于mysql - 连接几个表的 SQL 查询 (MySQL),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25678437/

相关文章:

mysql - 8 表连接和选择 count(distinct()) 未正确返回

php - 如果不是当前日期,则将 SQL 日期变为红色

c# 无法连接到任何指定的 MySQL 主机

Php和mysql登录脚本

mysql - 为什么 MySQL 不使用这些可能的键中的任何一个?

PHP/MySQL 数组/numrows 交叉表

mysql - 你如何使用 JOIN 而没有 ID 进行删除?

mysql - SQL Like 运算符

c++ - 为什么在没有编写器的命名管道上选择无限期阻塞?

jquery - 在选择标签上使用 val(...) 时触发更改