首页 > 解决方案 > 如何在mysql中对一个值进行多次检查

问题描述

这是我的桌子

在此处输入图像描述

假设:

..如果ID的最后一个有效条目是1,那么它很好

..如果 id 的最后一个有效条目是 0,则意味着检查有效为 1 之前的条目

..如果一个ID的最后一个有效条目为空,那么它一无是处

现在我想做的是

  1. 获取该 ID 的最后一个条目获得 1 作为有效值的那些 ID

  2. 如果 id 的最后一个条目的有效值为 0,那么它将采用有效值为 1 的条目之前的条目。

  3. 如果 id 的最后一个条目的“有效”为 0,但上面的值为 null,则结果中完全避免了该 id

不,这是我想要达到的结果

在此处输入图像描述

那么如何完成这项工作。

如何为此编写sql。

提前致谢。

标签: mysqlsql

解决方案


MySQL 的未来版本将具有横向连接

这是为了未来。未来已经到来,我在 MySQLWorkbench 上运行下面的查询,使用 MySQL 版本 8.0.15,横向连接有效。

不过,现场测试是针对 Postgres 的。db-fiddle.com 上还没有 MySQL 8.0.15,它只有 8.0.12 版本。

现场测试:https ://www.db-fiddle.com/f/jQwSuyJ8Vwr3inaty6XVk7/1

with lr as -- gets last row of each id
(
    select  tbl.*
    from (select id, max(no) as max_no from tbl group by id) as ln 
    join tbl on (ln.id,ln.max_no) = (tbl.id,tbl.no) 
)
select x.*
from lr
cross join lateral
(
    select tbl.*
    from tbl 
    where
        -- valid = 1, good:
        lr.valid = 1 and tbl.no = lr.no

        -- valid = 0, check the one before it:
        or lr.valid = 0 and tbl.id = lr.id and tbl.no < lr.no

        -- optional. since it doesn't match anything here, no rows matched:
        --     or lr.valid is null and 1 = 0            
    order by tbl.no desc
    limit 1
) as x
where x.valid is not null
order by x.id;

输出:

| no  | id  | valid |
| --- | --- | ----- |
| 1   | 1   | 1     |
| 5   | 2   | 1     |
| 10  | 4   | 1     |
| 16  | 6   | 1     |

MySQL 8.0.15 在 dbfiddle.uk 上可用:https ://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=95a873135d22bcfce3e59839d283e9a0


Postgres 可以通过使用DISTINCT ON而不是加入 max(no) 来缩短:

现场测试:https ://www.db-fiddle.com/f/jQwSuyJ8Vwr3inaty6XVk7/2

with lr as -- gets last row of each id
(
    select distinct on (id) 
        *
    from tbl
    order by id, no desc
)

推荐阅读