我正在尝试查找具有一组精确匹配值的行。
例如,如果我正在查找 ID 0,1 和 2,我将使用值 ((7,2),(3,2),(7,1)) 查询类型、大小和名称日期。
ID Type Size
----------------------
0 7 2
1 3 2
2 7 1
3 7 6
4 7 2
5 7 null
此查询的答案如下...(注意 ID 4 也会返回,因为它与 ID 0 具有相同的类型/大小)
ID Type Size
---------------------
0 7 2
1 3 2
2 7 1
4 7 2
我尝试使用以下查询来执行此操作
SELECT * FROM my_table WHERE (Type,Size) IN ((7,2),(3,2),(7,1))
但是,如果其中一个值不存在,则这不起作用,例如
SELECT * FROM my_table WHERE (type,size) IN ((7,2),(3,2),(7,99))
应该返回 null,因为 (7,99)
不存在
如果包含空值也会中断
这是关系除法与余数问题的变体。
您正在尝试从表中获取与输入集(除数)匹配的行集(被除数),但可能有重复项,这会使事情变得复杂。
一种解决方案是将主表左连接到要查找的数据,然后通过检查
COUNT(*)
是否等于 COUNT(maintable.id)
来查找丢失的行,如果所有内容都匹配,就会这样做。我们需要将这个计数作为窗口函数来执行,因为我们希望最终结果包含所有行,而不仅仅是是/否答案。
我们可以使用
IS NOT DISTINCT FROM
来正确比较空值。
WITH ToFind(type, size) AS (
VALUES
(7::int,2::int),
(3,2),
(7,99)
),
Matches AS (
SELECT
mt.*,
COUNT(*) OVER () - COUNT(mt.id) OVER () AS countMissing
FROM ToFind tf
LEFT JOIN my_table mt
ON (tf.type, tf.size) IS NOT DISTINCT FROM (mt.type, mt.size)
)
SELECT
m.id,
m.type,
m.size
FROM Matches m
WHERE m.countMissing = 0;