Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 如何在父查询case语句中使用子查询的结果_Mysql_Sql_Datetime_Subquery_Lateral Join - Fatal编程技术网

Mysql 如何在父查询case语句中使用子查询的结果

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的结果,但我得到一个

我有以下返回预期结果的查询:

选择 地点。*, 选择 身份证件 从…起 拖运 哪里 拖运类型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 从…起 位置
您可以使用子查询或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。谢谢你的建议谢谢。这就是我最终使用的解决方案。谢谢。我最终使用了另一种解决方案,但感谢您指出可能的性能问题。如果遇到性能问题,我会将此解决方案放在附近。