【问题标题】:MySQL: Add a WHERE in a LEFT JOINMySQL:在 LEFT JOIN 中添加 WHERE
【发布时间】:2020-02-18 14:27:14
【问题描述】:

我有下表:

SequenceNumber 始终是 10 的倍数。对于特定的cpId,我想获得最小的空闲序列号(仍然是 10 的倍数)。例如,对于cpId = 1,可用的最小应该是20。对于cpId = 2,应该是10

我有以下语句来获取所有cpId的最小可用sequenceNumber,但我不知道如何在语句中添加WHERE cpId = x

SELECT MIN(t1.sequenceNumber + 10) AS nextID
FROM LogicalConnection t1
   LEFT JOIN LogicalConnection t2
       ON t1.sequenceNumber + 10 = t2.sequenceNumber
WHERE t2.sequenceNumber IS NULL;

数据库小提琴:https://www.db-fiddle.com/f/ag67AkFzfwPZEva8bTN7Q3/2#&togetherjs=L9nHb3Uu7O

感谢您的帮助!

【问题讨论】:

  • 您是否知道如果您有并发事务,您的方法会惨败?
  • @a_horse_with_no_name 是的,这是受信号量保护的。
  • 如果你想要序列号最小的记录,为什么cpId = 1,最小的是20cpId = 2最小的是10?请帮助我理解。
  • @sveer 第一个序列号是 10,然后它总是递增 10 (10,20,30,40...)。对于 cpId =1,使用 10 和 30,但不是 20,所以这是最小的可用值(我不使用 0)。对于 cpId = 2,不使用 10,这是最小的。

标签: mysql sql left-join


【解决方案1】:

你可以使用lead()得到下一个数字,然后一些简单的逻辑:

select cpid,
       (case when min_sn > 10 then 10
             else min(sequenceNumber) + 10
        end)
from (select t.*,
             min(sequenceNumber) over (partition by cpid) as min_sn,
             lead(sequenceNumber) over (partition by cpid order by sequenceNumber) as next_sn
      from t
     ) t
where next_sn is null or next_sn <> sequenceNumber + 10
group by cpid, min_sn;

【讨论】:

    【解决方案2】:

    您必须在 cpId 列上连接两个表,并将具有相似 cpId 的行分组。 Where 可用于过滤行。 下面的查询为您提供 cpId 及其对应的下一个可用最小序列号。

    SELECT t1.cpId, MIN(t1.sequenceNumber + 10) AS nextID
    FROM LogicalConnection t1
    LEFT JOIN LogicalConnection t2
           ON t1.sequenceNumber + 10 = t2.sequenceNumber
           and t1.cpId = t2.cpId
    group by (t1.cpId)
    

    【讨论】:

    • 对于 cpId = 2,这将返回 30 而不是 10。将尝试修改您的语句 :)
    猜你喜欢
    • 1970-01-01
    • 2011-07-06
    • 2016-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多