MySQL:引用子查询列
我目前正在为一个需要显示订单延迟多久的电子商务系统进行报告。我有订单的预计交货日期的日志,并能够获得最初和最后日期,但做比较预计日期等更复杂的事情证明是有问题的。MySQL:引用子查询列
A(简体版)我的查询如下:
SELECT orders.order_id,
orders.date_dispatched AS actual_dispatch_date,
(
SELECT projected_date
FROM order_delivery_projections
WHERE order_id = orders.order_id
ORDER BY order_delivery_projection_id ASC
LIMIT 1
) AS initial_delivery_projection,
(
SELECT projected_date
FROM order_delivery_projections
WHERE order_id = orders.order_id
ORDER BY order_delivery_projection_id DESC
LIMIT 1
) AS final_delivery_projection
FROM orders
-- and some other joins here for additional report data
(仅供参考,我在整理上的ID,而不是日期这里,因为调度预测可以向前和向后,例如如果库存货物提前发货)。
这样可以提取一些有关订单预计交货历史的原始数据,但我想对数据进行一些额外的分析,例如初始预计出货日期,最终预计出货日期预计出货日期和实际发货日期。这是我遇到麻烦的地方。
我试着在我的SELECT子句中添加一个DATEDIFF(final_delivery_projection, initial_delivery_projection)
列,以便查看给定的传递预测已经下滑了多少天,但是MySQL不会拥有它。在字段列表
SELECT orders.order_id,
orders.date_dispatched AS actual_dispatch_date,
(
SELECT projected_date
FROM order_delivery_projections
WHERE order_id = orders.order_id
ORDER BY order_delivery_projection_id ASC
LIMIT 1
) AS initial_delivery_projection,
(
SELECT projected_date
FROM order_delivery_projections
WHERE order_id = orders.order_id
ORDER BY order_delivery_projection_id DESC
LIMIT 1
) AS final_delivery_projection,
DATEDIFF(final_delivery_projection - initial_delivery_projection) AS projection_days_revised
FROM orders
-- and some other joins here for additional report data
未知列final_delivery_projection想必你不能在select语句如果别名指的是子选择在同一语句中使用别名。
我也希望能够根据预测的结果排除WHERE子句中的顺序。例如,我想排除最终预计出货日期在最初预计日期之前下落的所有订单,理由是我只对正在进行的订单感兴趣,而不是提前发货的订单。
正在提取和处理我试图在同一个语句中获得的数据,或者我将不得不在客户端做一些后处理来处理类似这样的事情?如果在SQL中是可行的,那么它是如何完成的?
我花了很多时间研究这个问题,这个问题是与MySQL的一个基本问题,这意味着你不能引用外部查询在内部查询中,如果内部查询位于查询的FROM部分中,即使您可以在内部查询位于SELECT部分时引用外部查询。
至于从交货日期历史记录中获取第一个和最后一个记录,我发现了这个查询可以产生可接受的性能的正确结果。
SELECT odr.order_id,
first_change.projected_date AS initial_projected_dispatch_date,
last_change.projected_date AS final_projected_dispatch_date
FROM order AS odr
LEFT JOIN (
SELECT
order_id,
MIN(order_delivery_projection_id) AS first_id,
MAX(order_delivery_projection_id) AS last_id
FROM order_delivery_projections
GROUP BY order_id
) AS change_record_finder ON change_record_finder.order_id = odr.order_id
LEFT JOIN order_delivery_projections AS first_change ON first_change.order_delivery_projection_id = change_record_finder.first_id
LEFT JOIN order_delivery_projections AS last_change ON last_change.order_delivery_projection_id = change_record_finder.last_id
WHERE -- where clauses go here
马特的解决方案将在其他SQL口味很成功,但MySQL的缺乏所需要的功能,让他以其他方式正确答案的工作。
我相信select的值是同时生成的。所以日期差异可能无法计算,因为当时可能不知道别名值。如果你重构Select,你可能会得到你正在寻找的结果。此外,这可以让您访问额外的表值,您可能需要额外的表值来进一步分析子查询/数据集。
SELECT orders.order_id,
orders.date_dispatched AS actual_dispatch_date,
First.Projected_Date AS initial_delivery_projection,
Current.Projected_Data AS final_delivery_projection,
dateDiff(Current.Projected_date,First.Projected_date)
FROM orders O
LEFT JOIN (SELECT projected_date, Order_ID
FROM order_delivery_projections
ORDER BY order_delivery_projection_id ASC
LIMIT 1) First
ON First.order_id = O.order_id
LEFT JOIN (SELECT projected_date, Order_ID
FROM order_delivery_projections
ORDER BY order_delivery_projection_id DESC
LIMIT 1)
ON Current.Order_ID = O.Order_ID
order_Delivery_projections中可能不存在Orders中的Order_ID吗?如果是这样,日期差异空值也可能导致错误...
环顾四周你需要使用派生表,以便访问选择查询中的别名。看到here从更多信息
尝试此查询:
SELECT orders.order_id,
orders.date_dispatched AS actual_dispatch_date,
initial_delivery_projection,
final_delivery_projection,
DATEDIFF(final_delivery_projection - initial_delivery_projection) AS projection_days_revised
FROM (
SELECT orders.order_id,
orders.date_dispatched AS actual_dispatch_date,
(
SELECT projected_date
FROM order_delivery_projections
WHERE order_id = orders.order_id
ORDER BY order_delivery_projection_id ASC
LIMIT 1
) AS initial_delivery_projection,
(
SELECT projected_date
FROM order_delivery_projections
WHERE order_id = orders.order_id
ORDER BY order_delivery_projection_id DESC
LIMIT 1
) AS final_delivery_projection
FROM orders) z
DATEDIFF的语法是否正确? 'DATEDIFF(datepart,startdate,enddate)'是我使用的。 – Matt
我在DATEDIFF上没有收到任何语法错误,文档说它只有两个参数 – GordonM