我有一个非常简单的表:
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方式可以解决此问题。请告知。
答案 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_a
和user_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
表示您要搜索的a
或b
的值。