MySQL-选择其中value = X的行,如果没有匹配,则选择value = null的行

时间:2018-12-19 13:42:11

标签: mysql

如何查找表val_b中具有特定值的所有行,但是如果不存在这样的行,我想查看是否存在匹配性较低的行,因此val_b为{ {1}}。

从下表中,我想选择nullval_a = X的位置,并返回带有val_b = T的行。

如果我选择ID:1val_a = X的位置,并返回带有val_b = VID:3的行。由于行ID:41不匹配,因此我将解决具有较低特异性但仍匹配2的行。

val_a

这可以直接在数据库查询中执行吗?类似于语法上与左相关的| ID | val_a | val_b | | -- | ----- | ----- | | 1 | X | T | | 2 | X | U | | 3 | X | null | | 4 | X | null | | 5 | Y | null | 运算符...

1 个答案:

答案 0 :(得分:1)

尝试此查询:

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));

enter image description here

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

但是请注意,即使在这种情况下,我们仍然需要使用子查询。