如果某些值不匹配,如何返回默认行?

时间:2020-01-07 08:01:11

标签: sql postgresql

我有一个非常简单的表:

create table mydata (id integer, data character varying(255), a integer, b integer);
insert into mydata values 
(1, 'both a and b not found', null, null), 
(2, 'a=not found, b=20',      null,   20), 
(3, 'a=10, b=not found',        10, null), 
(4, 'a=10, b=20',               10,   20),
(... more rows with unique combinations of a and b);

我需要一个查询,该查询针对a和b的任何值返回准确的一行。

如果找到a和b的两个值,则应选择指定的行(在此示例中为id = 4)。

如果未找到这些值,但是在b列中有一行与a的值匹配并且为空,则该行应为此特定a和未知b定义默认值。同样,如果找到了b但没有找到a,并且存在一个值为b的行,并且在a列中为null,则这是该情况的默认设置。

如果找不到这样的默认值,但是在a和b列中存在一个空值行,则该行指定常规默认值。

最后,如果该行也不存在,则返回零行。

http://sqlfiddle.com/#!17/a5173/5

就目前而言,我已经通过一些Java代码解决了该问题,该代码运行多个特定的sql查询,直到找到匹配项为止,但是我想有一种sql方式可以解决此问题。请告知。

2 个答案:

答案 0 :(得分:5)

SELECT * FROM mydata
WHERE (coalesce(a, user_a), coalesce(b, user_b)) = (user_a, user_b)
ORDER BY a IS NULL, b IS NULL
LIMIT 1;

user_auser_b是您要查询的值。

答案 1 :(得分:0)

嗯,也许您可​​以先过滤可能的候选者,然后在CASE子句中使用ORDER BY表达式按优先级对候选者进行排序。通过LIMIT子句选择最上面的一个。

SELECT *
       FROM mydata
       WHERE a = :a
             AND b = :b
              OR a = :a
                 AND b IS NULL
               OR a IS NULL
                  AND b = :b
                OR a IS NULL
                   AND b IS NULL
       ORDER BY CASE
                  WHEN a = :a
                       AND b = :b THEN
                    1
                  WHEN a = :a
                       AND b IS NULL THEN
                    2
                  WHEN a IS NULL
                       AND b = :b THEN
                    3
                  WHEN a IS NULL
                       AND b IS NULL THEN
                    4
                END
       LIMIT 1;

:a:b表示您要搜索的ab的值。