如何查找where子句中排除数据的哪一部分?

时间:2019-01-15 13:42:57

标签: mysql

我有这样的查询 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 。有没有更有效的方法来执行此操作或最佳做法?

目标是用排除的原因标记排除的数据行。

3 个答案:

答案 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')