我有这样的查询 A :
SELECT * FROM my_table WHERE foreign_key = 'abc' AND field1 = 'foo' AND field2 = 'bar';
与数据的超集相比,有没有办法找出where子句的哪一部分负责数据的排除?例如,与查询 B 相比:
SELECT * FROM my_table WHERE foreign_key = 'abc';
我知道您可以在单独的查询中使用where子句的每个部分,并采用不同数量的查询 B 。有没有更有效的方法来执行此操作或最佳做法?
目标是用排除的原因标记排除的数据行。
答案 0 :(得分:2)
我将使用简化查询进行回答:
SELECT *
FROM my_table
WHERE field1 = 'foo' AND field2 = 'bar';
我们可以尝试使用CASE
表达式来标记失败原因:
SELECT
id,
CASE WHEN (field1 <> 'foo' OR field1 IS NULL) AND
(field2 <> 'bar' OR field2 IS NULL)
THEN 'field1,field2'
WHEN (field1 <> 'foo' OR field1 IS NULL)
THEN 'field1'
WHEN (field2 <> 'bar' OR field2 IS NULL)
THEN 'field2'
ELSE 'pass' END AS reason
FROM my_table;
请注意,该查询实际上没有WHERE
子句;它会返回所有记录,每个记录要么标记为通过,要么标记将导致失败的字段。
答案 1 :(得分:2)
用来标记排除的数据行以及排除的原因。
然后大概您想查看以前被排除的数据,这意味着您需要从WHERE子句中删除谓词。如果将它们简单地添加到SELECT子句中,您将看到满足哪些条件-
SELECT *,
(foreign_key = 'abc') AS foreign_key_rule,
(field1 = 'foo') AS field1_rule,
(field2 = 'bar') AS field2_rule
FROM my_table WHERE 1;
答案 2 :(得分:1)
您可以执行以下操作来找出为什么排除行的行:
select
id,
case
when coalesce(foreign_key, '') != 'abc' then 'foreign_key not "abc"'
when coalesce(field1, '') != 'foo' then 'field1 not "foo"'
when coalesce(field2, '') != 'bar' then 'field2 not "bar"'
end as exclusion_reason
from my_table
where not (foreign_key = 'abc' AND field1 = 'foo' AND field2 = 'bar')
请注意,where
子句通过被包裹在not (...)
中而被否定,因此仅返回排除的行。
您可以修改它以标记排除的行,如下所示:
update my_table set
exclusion_reason = case
when coalesce(foreign_key, '') != 'abc' then 'foreign_key not "abc"'
when coalesce(field1, '') != 'foo' then 'field1 not "foo"'
when coalesce(field2, '') != 'bar' then 'field2 not "bar"'
end
where where not (foreign_key = 'abc' AND field1 = 'foo' AND field2 = 'bar')