postgresql SQL过滤一组精确的值

zqdjd7g9  于 5个月前  发布在  PostgreSQL
关注(0)|答案(1)|浏览(85)

我试图找到具有一组精确匹配值的行。
例如,如果我正在查找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     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)不存在
如果包含空值,它也会中断
https://www.db-fiddle.com/f/2vxEEQNMhnK9oFGAhrQXip/2

yvfmudvl

yvfmudvl1#

这是Relational Division With Remainder问题的一个变体。

您试图从表中获取与输入集(除数)匹配的行集(被除数),但是可能会有重复的行,这会使事情变得复杂。
一个解决方案是左连接主表到要查找的数据,然后通过检查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;

字符串
db<>fiddle

相关问题