【问题标题】:Find next / previous number in mysql table在mysql表中查找下一个/上一个数字
【发布时间】:2020-05-29 19:32:00
【问题描述】:

鉴于此表:

contractnumber | itemnumber
1234           | 100151
1234           | 100152
1235           | 100127
1235           | 100128
1236           | 100001
1236           | 100002

在给定 itemnumber 的 table order 是 contractnumber ASC,itemnumber ASC 之后,如何从表中获取下一个(或上一个)itemnumber?

例如,我想获取 100128 (100128) 之后的下一个 itemnumber 或上一个 itemnumber 到 100001 (100128)。

【问题讨论】:

  • 使用LEAD/LAG
  • 你的MySql是什么版本的?
  • MySQL 5.7.30(在 ubuntu 18.04 上),对于 LEAD / LAG 来说太旧了
  • itemnumber 是否唯一?
  • 是的,itemnumber 是唯一的

标签: mysql mysql-5.7


【解决方案1】:

在 MySQL 5.x 中,您不能使用 LEAD()LAG()。但是,您可以对行进行排序并将结果集限制为 1 行。见下文

对于100128下一个元素,您可以使用:

select *
from t
where (contractnumber, itemnumber) > (
  select contractnumber, itemnumber from t where itemnumber = 100128
)
order by contractnumber, itemnumber 
limit 1;

结果:

contractnumber  itemnumber
--------------  ----------
          1236      100001

对于100128上一个元素,您可以使用:

select *
from t
where (contractnumber, itemnumber) < (
  select contractnumber, itemnumber from t where itemnumber = 100128
)
order by contractnumber desc, itemnumber desc
limit 1;

结果:

contractnumber  itemnumber
--------------  ----------
          1235      100127

请参阅DB Fiddle 的运行示例。

【讨论】:

  • 您在查询中使用未给出的contractnumber = 1235。
  • 这看起来很简单,但我必须先得到合同编号,这对我来说不是问题。
  • @jlai79 ...但是您确实需要使用contractnumber,不是吗?您是在暗示没有必要;这意味着itemnumber 是表上的唯一键。是这样吗?
  • 现在,如果itemnumber 是桌上的钥匙,那么整个问题就没有多大意义了。
  • 也许这是一个愚蠢的问题。我只是不知道我可以做一个“哪里(合同编号,项目编号)
【解决方案2】:

由于每个contractnumber 可能存在不同的itemnumbers,它并不像ORDER BYLIMIT 1 那样简单。
您还必须检查下一个/上一个itemnumber 具有相同contractnumber 的情况。

对于上一条100128:

select
  coalesce(
    (
      select min(itemnumber) from tablename 
      where contractnumber = (
        select contractnumber from tablename 
        where itemnumber = 100128
      ) and itemnumber > 100128
    ),
    (
      select itemnumber from tablename
      where contractnumber > (
        select contractnumber from tablename 
        where itemnumber = 100128
      )
      order by contractnumber, itemnumber limit 1
    )  
  ) itemnumber

对于 100001 的下一项:

select
  coalesce(
    (
      select max(itemnumber) from tablename 
      where contractnumber = (
        select contractnumber from tablename 
        where itemnumber = 100001
      ) and itemnumber < 100001
    ),
    (
      select itemnumber from tablename
      where contractnumber < (
        select contractnumber from tablename 
        where itemnumber = 100001
      )
      order by contractnumber desc, itemnumber desc limit 1
    )  
  ) itemnumber

请参阅demo

【讨论】:

  • 这似乎可行,但看起来比 The Impaler 的其他解决方案更复杂。
  • 如果您提到您知道合同编号,那就不复杂了。
  • 当 itemnumber 唯一时,您可以轻松选择合同编号。我看到我的问题不够清楚。对此感到抱歉
  • 这就是为什么我在查询中使用:select contractnumber from tablename where itemnumber = ? 来获取项目编号的合同编号。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-10
  • 1970-01-01
  • 1970-01-01
  • 2016-07-25
相关资源
最近更新 更多