如何在表中找到val_b具有特定值的所有行,但如果不存在这样的行,我想看看是否存在匹配特异性较低的行,因此val_b为null.
从下表中,我想选择val_a = X和val_b = T的位置,并获取ID为1的行.
如果我选择val_a = X和val_b = V的位置并获取ID为3且ID为4的行.由于第1行和第2行不匹配,我将解决具有较低特异性但仍匹配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));
Demo
这里的逻辑是,如果满足下列条件之一,我们将保留记录:
> val_b匹配预期的(非NULL)值,或
> val_b为NULL,并且没有匹配的非NULL val_b记录
EXISTS子句涵盖了第二种情况,它断言没有匹配的非NULL val_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));
Demo
但请注意,即使在这种情况下,我们仍然需要使用子查询.