Mysql 如何在父查询case语句中使用子查询的结果
我有以下返回预期结果的查询: 选择 地点。*, 选择 身份证件 从…起 拖运 哪里 拖运类型id=1 和location_id=locations.id 订购人 在DESC创建_ 限制1作为最后的交付id, 选择 身份证件 从…起 拖运 哪里 拖运类型id=2 和location_id=locations.id 订购人 在DESC创建_ 限制1作为最后一个拾取id 从…起 位置 我想在父查询的case语句中使用子查询last_delivery_id、last_picku_id的结果,但我得到一个错误: 错误:未知列“上次交货\u id” 选择 地点。*, 当上次交货id=1时,则为“待定”,当上次交货id=2时,则为“活动”结束状态, 选择 身份证件 从…起 拖运 哪里 拖运类型id=1 和location_id=locations.id 订购人 在DESC创建_ 限制1作为最后的交付id, 选择 身份证件 从…起 拖运 哪里 拖运类型id=2 和location_id=locations.id 订购人 在DESC创建_ 限制1作为最后一个拾取id 从…起 位置Mysql 如何在父查询case语句中使用子查询的结果,mysql,sql,datetime,subquery,lateral-join,Mysql,Sql,Datetime,Subquery,Lateral Join,我有以下返回预期结果的查询: 选择 地点。*, 选择 身份证件 从…起 拖运 哪里 拖运类型id=1 和location_id=locations.id 订购人 在DESC创建_ 限制1作为最后的交付id, 选择 身份证件 从…起 拖运 哪里 拖运类型id=2 和location_id=locations.id 订购人 在DESC创建_ 限制1作为最后一个拾取id 从…起 位置 我想在父查询的case语句中使用子查询last_delivery_id、last_picku_id的结果,但我得到一个
您可以使用子查询或CTE:
SELECT lh.*, . . . -- any expressions you want
(case when last_delivery_id = 1 then 'pending'
when last_delivery_id = 2 then 'active'
end) as status
FROM (SELECT l.*,
(SELECT id
FROM hauls h
WHERE h.haul_type_id = 1 AND
h.location_id = l.id
ORDER BY h.h.created_at DESC
LIMIT 1
) AS last_delivery_id,
(SELECT id
FROM hauls h
WHERE h.haul_type_id = 2 AND
h.location_id = l.id
ORDER BY h.created_at DESC
LIMIT 1
) AS last_pickup_id
FROM locations l
) lh
请注意,表别名的使用使查询更易于编写和读取。也就是说,如果您只想要字符串版本,我不确定您是否真的需要交付id:
SELECT l.*,
(SELECT (case when h.id = 1 then 'pending'
when h.id = 2 then 'active'
end)
FROM hauls h
WHERE h.haul_type_id = 1 AND
h.location_id = l.id
ORDER BY h.created_at DESC
LIMIT 1
) AS status
FROM locations l
考虑使用CTE和window函数重新编写内联子查询。这避免了使用限制条款,如果不是最佳运行的话,限制条款可能会有。这需要MySQL版本8.0+,它支持CTEs和窗口功能: 以sub为例 选择id作为最后一次交付\u id ,位置_id ,拖运类型\u id ,按位置id、运输类型id划分的分区上的行号 在描述处创建的订单为rn 拖运 选择L*-考虑显式选择列的性能 案例 当h1.last_delivery_id=1时,则为“待定” 当h2.last_delivery_id=2时,则为“活动” 以`身份'结尾` 从地点l 左连接接头h1 在h1.location_id=l.id上 和h1.1.1类型id=1 h1.rn=1 左连接子h2 在h2.location_id=l.id上 和h2.hull_type_id=2 h2.rn=1
对于早期版本如果您运行的是MySQL 8.0.14或更高版本,您可以使用横向联接:
select l.*, h1.*, h2.*
case
when last_delivery_id = 1 then 'pending'
when last_delivery_id = 2 then 'active'
end as status
from locations l
left join lateral (
select h.id as last_delivery_id
from hauls h
where h.haul_type_id = 1 and h.location_id = l.id
order by h.created_at desc limit 1
) h1 on true
left join lateral (
select h.id as last_pickup_id
from hauls h
where h.haul_type_id = 2 and h.location_id = l.id
order by h.created_at desc limit 1
) h2 on true
横向连接是一个强大的功能,MySQL已经丢失了很长时间。例如,上面的语句可以很容易地调整为从每个子查询返回更多的列。因为select part中的所有列一次全部执行,而last_delivery_id列尚未创建,并且您尝试使用它,sql server返回一个错误,要解决它,您可以使用CTE,查看和驱动表。将第一个查询用作子查询,然后可以选择并使用两个派生列。谢谢。我喜欢这个,但不幸的是不能使用MySQL 8。谢谢你的建议谢谢。这就是我最终使用的解决方案。谢谢。我最终使用了另一种解决方案,但感谢您指出可能的性能问题。如果遇到性能问题,我会将此解决方案放在附近。