mysql - MySQL - 选择 value = X 的行,或者如果没有匹配,则 value = null
问题描述
如何在val_b
具有特定值的表中找到所有行,但如果不存在这样的行,我想看看是否存在匹配度较低的行,因此 val_b 在哪里null
。
从下表中,我想选择位置val_a = X
并val_b = T
获取ID:1
后面的行。
如果我选择where val_a = X
and val_b = V
get row with ID:3
and ID:4
back。由于 row 1
and 2
didn't match,我将解决那些特异性较低但仍然 match 的行val_a
。
| ID | val_a | val_b |
| -- | ----- | ----- |
| 1 | X | T |
| 2 | X | U |
| 3 | X | null |
| 4 | X | null |
| 5 | Y | null |
这可以直接在数据库查询中执行吗?类似于语法左关联XOR
运算符...
解决方案
试试这个查询:
SELECT ID, val_a, val_b
FROM yourTable
WHERE
val_a = 'X' AND (val_b = 'V' OR
(NOT EXISTS (SELECT 1 FROM yourTable
WHERE val_a = 'X' AND val_b = 'V') AND val_b IS NULL));
演示
这里的逻辑是,如果以下条件之一为真,我们将保留一条记录:
val_b
匹配预期的(非 NULL)值,或val_b
为 NULL并且没有匹配的非 NULLval_b
记录
该EXISTS
子句涵盖了第二种情况,它断言没有匹配的非 NULLval_b
记录。
搜索时,val_a = 'X'
使用上述查询val_b = 'T'
仅返回记录。ID:1
如果您使用的是 MySQL 8+,那么我们可以在这里使用分析函数:
WITH cte AS (
SELECT ID, val_a, val_b,
COUNT(CASE WHEN val_a = 'X' AND val_b = 'V' THEN 1 END)
OVER () cnt
FROM yourTable
)
SELECT ID, val_a, val_b
FROM cte
WHERE val_a = 'X' AND (val_b = 'V' OR (val_b IS NULL AND cnt = 0));
演示
但请注意,即使在这种情况下,我们仍然需要使用子查询。
推荐阅读
- python - 使用文件搜索另一个文件并打印与第一个文件匹配的模式的行
- html - 无法从 ionic 中的 observable json 对象绑定值
- sql - 如何从一个日期早于另一个表的表中加入最后一条记录?
- angular - Angular 8 - Typescript > ERROR TypeError:array.find 不是函数
- python - 无法访问数据框中特定列的值
- c - 使用双指针复制 LinkedList
- spring - 405 Method is not Allowed 异常:GET调用的“请求方法'T'不支持”和POST的“请求方法'ST'不支持”
- mongodb - 使用 Spring Boot 的 MongoDB 查询结果与预期不符
- javascript - 反应比较或匹配两个日期
- sql - 在 liquibase 上为 H2 数据库创建 SQL 函数