MySQL: 引用子查询列
MySQL: Referencing subquery columns
我目前正在为需要显示订单延迟时间的电子商务系统编写一些报告。我有一份订单的预计交货日期日志,并且能够获得初始日期和最后日期,但是做更复杂的事情(例如比较预计日期)证明是有问题的。
我的查询(简化版)如下:
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
Unknown column final_delivery_projection in field list
如果别名在同一语句中引用子select,则您不能在select 语句中使用别名。
我还希望能够根据预测结果排除 WHERE 子句中的订单。例如,我想排除所有最终预计发货日期早于初始预计发货日期的订单,因为我只对被搁置的订单感兴趣,而不是那些提前发货的订单。
是否可以在同一条语句中提取和处理我尝试获取的数据,或者我是否必须在客户端中进行一些 post 处理才能解决此类问题?如果在SQL可以,那怎么办呢?
我相信 select 的值是同时生成的。因此可能无法计算日期差异,因为当时可能不知道别名值。如果重构 Select,您可能会得到想要的结果。此外,这将使您能够访问额外的 table 值,您可能希望对子 queries/data 集进行额外分析。
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 中不存在订单中的 Order_ID?如果是这样,那么空值上的日期差异也可能导致错误...
环顾四周,您需要使用派生表才能访问 select 查询中的别名。从更多信息中查看 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
我花了很多时间研究这个问题,这个问题是 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
Matt 的解决方案在其他 SQL 风格中也适用,但 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
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
Unknown column final_delivery_projection in field list
如果别名在同一语句中引用子select,则您不能在select 语句中使用别名。
我还希望能够根据预测结果排除 WHERE 子句中的订单。例如,我想排除所有最终预计发货日期早于初始预计发货日期的订单,因为我只对被搁置的订单感兴趣,而不是那些提前发货的订单。
是否可以在同一条语句中提取和处理我尝试获取的数据,或者我是否必须在客户端中进行一些 post 处理才能解决此类问题?如果在SQL可以,那怎么办呢?
我相信 select 的值是同时生成的。因此可能无法计算日期差异,因为当时可能不知道别名值。如果重构 Select,您可能会得到想要的结果。此外,这将使您能够访问额外的 table 值,您可能希望对子 queries/data 集进行额外分析。
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 中不存在订单中的 Order_ID?如果是这样,那么空值上的日期差异也可能导致错误...
环顾四周,您需要使用派生表才能访问 select 查询中的别名。从更多信息中查看 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
我花了很多时间研究这个问题,这个问题是 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
Matt 的解决方案在其他 SQL 风格中也适用,但 MySQL 缺乏必要的功能来让他的正确答案发挥作用。