1
votes

Pourquoi l'ordre alterné des filtres de requête ne me donne pas les mêmes résultats

Je travaille sur un rapport Jasper, j'essaye de faire une mise à jour en fonction des exigences du client cependant j'ai trouvé ce filtre simple qui ne donne pas les mêmes résultats ('N' = 'Y' OR 'N' = 'N' AND prod.XX_SalesContext_ID <> 1000100) vs ( 'Y' = 'Y' OR 'Y' = 'N' AND prod.XX_SalesContext_ID <> 1000100)

Le dernier filtre ignore le (prod.XX_SalesContext_ID <> 1000100) et me donne plus de résultats.

Comment sql traite-t-il réellement cette ligne?

Merci


1 commentaires

4 Réponses :


1
votes

1) 'Y' n'est jamais égal à 'N' donc supprimez cela (et l'autre clause inutile) et regardez ce qu'il vous reste

2) Utilisez toujours, toujours, toujours des crochets lorsque vous mélangez AND et OR afin que votre intention soit claire pour la base de données (et les autres développeurs) sur la façon de regrouper les vérités logiques

--only people called Lee who are 30 or Male
Name = 'Lee' AND (Age = 30 OR Gender = 'Male')

Est-ce que

--only 30 year olds called Lee, or anyone who is male
(Name = 'Lee' AND Age = 30) OR Gender = 'Male'

Ou est-ce

Name = 'Lee' AND Age = 30 OR Gender = 'Male'

Bien sûr, il existe des règles de priorité pour les opérateurs, et vous pouvez les connaître (la formulation de la question indique que vous ne les connaissez peut-être pas) et déterminez ce que fait la base de données, mais c'est beaucoup plus descriptif pour un autre humain qui doit lire et maintenir votre code, utiliser simplement des crochets pour exprimer clairement votre intention.

Si vous suivez la règle "utiliser des crochets lors du mélange de ET et OU", vous n'aurez pas besoin de vous rappeler si ET est plus important que OU


0 commentaires

0
votes

AND a la priorité sur OR , donc dans votre deuxième requête, la dernière partie ( prod.XX_SalesContext_ID <> 1000100 ) n'est pas évaluée car "Y" = "N" sera toujours faux.


0 commentaires

0
votes

En effet, AND a une priorité plus élevée que OR .

Ce qui signifie que ('Y' = 'Y' OR 'Y' = 'N' AND prod.XX_SalesContext_ID <> 1000100) est égal à:

('Y' = 'Y' OR ('Y' = 'N' AND prod.XX_SalesContext_ID <> 1000100)) qui depuis 'Y' = 'Y' est true affiche uniquement tous les enregistrements.

Enfin, je peux donner de meilleurs conseils si vous montrez plus de votre code. Ce que vous montrez est une version modifiée, oui?


0 commentaires

2
votes

Parce que l'opérateur AND a une priorité plus élevée que l'opérateur OR.

Votre 1ère condition:

true

équivaut à:

true or false

équivalent à:

true or (false and prod.XX_SalesContext_ID<>1000100)

équivalent à:

'Y' = 'Y' OR 'Y' = 'N' AND prod.XX_SalesContext_ID<>1000100

Donc cette 1ère condition renvoie toutes les lignes où prod.XX_SalesContext_ID 1000100 .
Et la 2ème condition:

prod.XX_SalesContext_ID<>1000100

équivaut à:

false or prod.XX_SalesContext_ID<>1000100

équivalent à:

false or (true and prod.XX_SalesContext_ID<>1000100)

équivalent à:

'N' = 'Y' OR 'N' = 'N' AND prod.XX_SalesContext_ID<>1000100

Donc, cette deuxième condition est évaluée à true et renvoie toutes les lignes.


0 commentaires