2
votes

Comment trouver dans quelle partie la clause exclut les données?

J'ai une requête A comme celle-ci:

SELECT * FROM my_table WHERE foreign_key = 'abc';

Existe-t-il un moyen de savoir quelle partie de la clause where était responsable de l'exclusion des données comparées à un sur-ensemble de données? Par exemple, comparé à la requête B

SELECT * FROM my_table WHERE foreign_key = 'abc' AND field1 = 'foo' AND field2 = 'bar';

Je sais que vous pouvez prendre chaque partie de la clause where dans une requête distincte et prendre la quantité de différence de la requête B . Existe-t-il un moyen plus efficace de le faire ou une meilleure pratique?

L'objectif est de marquer les lignes de données exclues avec une raison de leur exclusion.


2 commentaires

@Strawberry la question est abstraite et bien définie. OP ne cherche pas un "problème dans son code", mais une solution à un problème générique. Je ne pense pas qu'il ait besoin d'un MVCE.


Un «où» lui-même ne peut EXCLURE QUE des lignes. Peut-être souhaitez-vous avoir une colonne de sortie «raison» basée sur une condition? Voir "cas", par exemple: "sélectionner (cas quand ...) comme raison de .."


3 Réponses :


2
votes

Je vais répondre en utilisant la requête simplifiée:

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;

Nous pouvons essayer d'utiliser les expressions CASE pour étiqueter la cause de l'échec:

SELECT *
FROM my_table
WHERE field1 = 'foo' AND field2 = 'bar';

Notez que cette requête n'a pas réellement de clause WHERE ; il renvoie tous les enregistrements, chacun étiqueté soit comme une réussite, soit avec les champs qui provoqueraient l'échec.


0 commentaires

1
votes

Vous pouvez faire quelque chose comme ceci pour savoir pourquoi les lignes seraient exclues:

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

Notez que la clause where a été annulé, en étant enveloppé dans not (...) , de sorte que seules les lignes exclues sont renvoyées.

Vous pouvez l'adapter pour marquer les lignes exclues comme ceci:

XXX


1 commentaires

Il est difficile de marquer LA bonne réponse à cette question, mais j'ai choisi cette réponse car elle semble élégante grâce à l'utilisation de coalesce et d'un exemple donné pour écrire directement la raison.



2
votes

consiste à marquer les lignes de données exclues avec une raison de leur exclusion.

Ensuite, vous voulez probablement voir les données qui avaient été précédemment exclues - ce qui signifie que vous devez supprimer les prédicats de la clause WHERE. Si vous les ajoutez simplement à la clause SELECT, vous verrez lesquels sont satisfaits et lesquels ne le sont pas -

SELECT *,
(foreign_key = 'abc') AS foreign_key_rule,
(field1 = 'foo') AS field1_rule,
(field2 = 'bar') AS field2_rule
FROM my_table WHERE 1;

0 commentaires