我在 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
), 交货的最后坐标 [LAT
和LNG
](基于最后的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/