Cam*_*Cam 6 mysql performance subquery select query-performance
过去 24 小时都在为某事挣扎。需要一些天才来发光。我正在尝试为驱动程序显示每周工作循环/日志,它将显示:
最后2点是我真正挣扎的地方。
我有以下表格:
drivers ('driver_id', 'driver_name')
vehicles ('vehicle_id', 'vehicle_make', 'vehicle_model')
jobs ('job_id', 'collection_address', 'collection_datetime', 'delivery_address', 'deliver_datetime', 'driver_id', 'vehicle_id')
Run Code Online (Sandbox Code Playgroud)
我附上了下面的输出屏幕:
例如,如果您查看 23/09/2016,司机 Keith 正在工作,但 Nick 有空。但是,如果我执行子查询,它会显示两个驱动程序,这不是正确的结果。我的 SQL 语句如下,如果有人可以提供帮助,我将不胜感激。
SELECT listofdays.job_date, j.job_id, IF( j.driver_id > 0 AND j.job_id > 0, (SELECT driver_name FROM t_drivers WHERE driver_id = j.driver_id LIMIT 1), '') as job_driver, IF( j.vehicle_id > 0, (SELECT vehicle_reg FROM t_vehicles WHERE vehicle_id = j.vehicle_id LIMIT 1), 'no') as job_vehicle, j.collection_town, j.collection_postcode, j.delivery_town, j.delivery_postcode, j.job_status
FROM (
SELECT '2016-09-19' + INTERVAL seq.seq DAY AS job_date
FROM seq_0_to_999999 AS seq
WHERE seq.seq <= TIMESTAMPDIFF(DAY , '2016-09-19', '2016-09-25' )
) AS listofdays
LEFT JOIN t_jobs j ON listofdays.job_date = DATE(j.collection_datetime)
ORDER BY DATE(listofdays.job_date), j.job_order ASC
Run Code Online (Sandbox Code Playgroud)
我也很高兴在速度和性能方面对上述查询进行任何改进。它将用于内部系统。
修订后的查询如下:
SELECT
sub.job_date,
j.job_id,
IFNULL(d.driver_name, '') as job_driver,
IFNULL(v.vehicle_reg, 'no') as job_vehicle,
j.collection_town,
j.collection_postcode,
j.delivery_town,
j.delivery_postcode,
j.job_status,
IF(j.job_id IS NULL, sub.available_drivers, 'no availability') AS available_drivers
FROM
(
SELECT
listofdays.job_date,
GROUP_CONCAT(d.driver_name) AS available_drivers
FROM
(
SELECT
'2016-09-19' + INTERVAL seq.seq DAY AS job_date
FROM
seq_0_to_999999 AS seq
WHERE
seq.seq <= TIMESTAMPDIFF(DAY, '2016-09-19', '2016-09-25')
) AS listofdays
CROSS JOIN t_drivers AS d
LEFT JOIN t_jobs AS j ON listofdays.job_date = DATE(j.collection_datetime)
AND d.driver_id = j.driver_id
GROUP BY listofdays.job_date
) AS sub
LEFT JOIN t_jobs AS j ON sub.job_date = DATE(j.collection_datetime)
LEFT JOIN t_drivers AS d ON j.driver_id = d.driver_id
LEFT JOIN t_vehicles AS v ON j.vehicle_id = v.vehicle_id
ORDER BY
job_date ASC,
job_order ASC
Run Code Online (Sandbox Code Playgroud)
输出如下:
如果您在 23 日查看上图,则有 2 个空缺职位,其中应该有可用驱动程序的列表,但它说没有可用的驱动程序。在我们的例子中,Nick 那天没有工作,但它说没有空。
我将从可用驱动程序列表开始。由于您似乎希望将它们作为 CSV 字符串,因此使用分组并使用 GROUP_CONCAT() 连接名称是有意义的。使用作业的外连接来计算日期和驱动程序的叉积,然后,要获取每天可用的驱动程序,仅当驱动程序名称没有匹配的作业时才对驱动程序名称进行分组连接:
\n\nSELECT\n listofdays.job_date,\n GROUP_CONCAT(IF(j.job_id IS NULL, d.driver_name, NULL)) AS available_drivers\nFROM\n (\n SELECT\n '2016-09-19' + INTERVAL seq.seq DAY AS job_date\n FROM\n seq_0_to_999999 AS seq\n WHERE\n seq.seq <= TIMESTAMPDIFF(DAY, '2016-09-19', '2016-09-25')\n ) AS listofdays\n CROSS JOIN t_drivers AS d\n LEFT JOIN t_jobs AS j ON listofdays.job_date = DATE(j.collection_datetime)\n AND d.driver_id = j.driver_id\nGROUP BY\n listofdays.job_date\n;\n
Run Code Online (Sandbox Code Playgroud)\n\n下一步也是最后一步是使用上面的作为派生表并再次外连接到它\ t_jobs
xe2\x80\x93 这次以获得作业详细信息(并且您还需要外连接t_drivers
并t_vehicle
也可以从这些表中获取详细信息):
SELECT\n sub.job_date,\n j.job_id,\n IFNULL(d.driver_name, '') as job_driver,\n IFNULL(v.vehicle_reg, 'no') as job_vehicle,\n j.collection_town,\n j.collection_postcode,\n j.delivery_town,\n j.delivery_postcode,\n j.job_status,\n sub.available_drivers\nFROM\n (\n SELECT\n listofdays.job_date,\n GROUP_CONCAT(IF(j.job_id IS NULL, d.driver_name, NULL)) AS available_drivers\n FROM\n (\n SELECT\n '2016-09-19' + INTERVAL seq.seq DAY AS job_date\n FROM\n seq_0_to_999999 AS seq\n WHERE\n seq.seq <= TIMESTAMPDIFF(DAY, '2016-09-19', '2016-09-25')\n ) AS listofdays\n CROSS JOIN t_drivers AS d\n LEFT JOIN t_jobs AS j ON listofdays.job_date = DATE(j.collection_datetime)\n AND d.driver_id = j.driver_id\n GROUP BY\n listofdays.job_date\n ) AS sub\n LEFT JOIN t_jobs AS j ON sub.job_date = DATE(j.collection_datetime)\n LEFT JOIN t_drivers AS d ON j.driver_id = d.driver_id\n LEFT JOIN t_vehicles AS v ON j.vehicle_id = v.vehicle_id\nORDER BY\n job_date ASC,\n job_order ASC\n;\n
Run Code Online (Sandbox Code Playgroud)\n
归档时间: |
|
查看次数: |
106 次 |
最近记录: |