【问题标题】:MySQL: Update on condition and select statementMySQL:更新条件和选择语句
【发布时间】:2020-11-17 14:10:53
【问题描述】:

我有带有 id、degree、roundAbout 和 action 的表格。我需要根据下一行的程度和动作值更新动作。 为了解释,需要做这样的事情。如果当前度数小于下一行度数且 roundAbout 为“N”,则操作应设置为“TurnRight”,如果当前度数大于下一行度数且 roundAbout 为“N”,则操作应设置为“TurnLeft”,如果 nxt行 roundAbout 为 'y' 那么无论度数动作都应设置为 'FollowRoundAbout'

我如何做到这一点? 这是我的表的例子

ID   |   degree  |  roundabout|
----------------------------
 1   |    30     |  N         |
 2   |   130     |  N         |
 3   |   330     |  N         |
 4   |   210     |  N         |
 5   |    30     |  Y         |

My expected table would be

ID   |   degree  |  roundabout|   action|
-----------------------------------------
 1   |    30     |  N         |   RIGHT
 2   |   130     |  N         |   RIGHT
 3   |   330     |  N         |   LEFT
 4   |   210     |  N         |   FollowRound
 5   |    30     |  Y         |   Stop

【问题讨论】:

  • 如果您不使用 MySql 8.0+,您可以使用滚动变量来存储前一行的 degreeroundabout 值,同时通过 @987654324 对表进行迭代@

标签: mysql sql aggregate


【解决方案1】:

对于 MySql 8.0+,您可以使用 LEAD() 窗口函数和自联接:

UPDATE tablename t1
INNER JOIN (
  SELECT *, 
         LEAD(degree) OVER (ORDER by ID) next_degree,
         LEAD(roundabout) OVER (ORDER by ID) next_roundabout
  FROM tablename
) t2 ON t2.id = t1.id
SET t1.action = CASE
  WHEN t2.next_roundabout = 'Y' THEN 'FollowRound'
  WHEN t1.degree < t2.next_degree AND t1.roundAbout = 'N' THEN 'RIGHT'
  WHEN t1.degree > t2.next_degree AND t1.roundAbout = 'N' THEN 'LEFT'
  ELSE 'STOP'
END; 

请参阅demo
结果:

> ID | degree | roundabout | action     
> -: | -----: | :--------- | :----------
>  1 |     30 | N          | RIGHT       
>  2 |    130 | N          | RIGHT       
>  3 |    330 | N          | LEFT      
>  4 |    210 | N          | FollowRound
>  5 |     30 | Y          | STOP   

【讨论】:

    【解决方案2】:

    这听起来像是带有窗口函数的case 表达式:

    select t.*,
           (case when next_roundabout = 'Y'
                 then 'Follow Roundabout'
                 when degree < next_degree and roundabout = 'N'
                 then 'TurnRight'
                 when degree > next_degree and roundabout = 'N'
                 then 'TurnLeft'
                 when next_degree is null
                 then 'Stop'
            end) as action
    from (select t.*,
                 lead(degree) over (order by id) as next_degree,
                 lead(roundabout) over (order by id) as next_roundabout
          from t
         ) t;
    

    如果您有 action 列,您可以将此结果保存到新表(或视图)中或更新现有表。

    【讨论】:

      【解决方案3】:

      解决方案:1

      select a.id, a.degree, a.roundabout, case when  a.degree < b.degree and b.roundabout = 'N' then  
      'RIGHT'    
      when  a.degree > b.degree and b.roundabout = 'N'
      THEN 'LEFT'
      when  b.roundabout = 'Y' then 'FollowRound'
      end
      as action
      from table1 a crossjoin table2 b
      where b.id = a.id + 1
      

      解决方案 2:

      select a.id, a.degree, a.roundabout, case when  a.degree < b.degree and b.roundabout = 'N' then  
          'RIGHT'    
          when  a.degree > b.degree and b.roundabout = 'N'
          THEN 'LEFT'
          when  b.roundabout = 'Y' then 'FollowRound'
          end
          as action from table a join table b on two.id = one.id + 1 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-04
        • 1970-01-01
        • 2014-07-22
        • 2021-08-25
        • 1970-01-01
        • 2014-11-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多