1
votes

Affichage des valeurs NULL dans la clause WHERE

J'ai rassemblé l'exemple ci-dessous pour expliquer ce que j'essaie de faire.

J'essaie de faire partie de la requête lorsque @FeatureID est NULL, puis renvoie tous les enregistrements dans la table # Temp pour ce ClientID . Si un @FeatureID contient un 1 par exemple, renvoyer l'enregistrement 1 et l'enregistrement NULL.

Où me suis-je trompé dans ma clause where?

CREATE TABLE #Temp
(
    ClientID int,
    FeatureID int
)

Insert into #Temp
(
    ClientID,
    FeatureID
)
SELECT
    1,
    1
UNION
SELECT
    1,
    2
UNION
SELECT
    1,
    3
UNION
SELECT
    1,
    NULL


Declare @ClientID int = 1
Declare @FeatureID int = NULL

--should return all 4 records
select * from #Temp 
where ClientID = 1 and 
FeatureID = IIF(@FeatureID IS NULL, FeatureID, @FeatureID)

Set @ClientID = 1
Set @FeatureID = 1

--should return the 1,1 record and the 1,NULL record
select * from #Temp 
where ClientID = 1 and 
FeatureID = IIF(@FeatureID IS NULL, FeatureID, @FeatureID)

drop table #Temp


0 commentaires

3 Réponses :


1
votes

Vous essayez effectivement de comparer NULL = NULL dans votre clause where qui ne fonctionne pas. NULL ne se compare pas à un autre NULL.

Pour votre première requête, ce que vous devez faire est de comparer uniquement la colonne d'ID de fonctionnalité lorsque @FeatureID n'est pas nul. Cela peut être accompli en testant la variable et en utilisant une condition OR.

select * from #Temp 
where ClientID = 1 and 
    (
        @FeatureID IS NULL 
        OR (@FeatureID IS NOT NULL AND (FeatureID IS NULL OR FeatureID=@FeatureID))
    )

Dans la deuxième requête, vous devez comparer la colonne d'ID de fonctionnalité à la fois à @FeatureID et à NULL pour obtenir les deux lignes.

--should return the 1,1 record and the 1,NULL record
select * from #Temp 
where ClientID = 1 and 
(@FeatureID IS NOT NULL AND (FeatureID IS NULL OR FeatureID=@FeatureID))

Pour gérer les deux cas dans une seule requête, utilisez deux conditions jointes par OR qui sont branchées selon que la variable est nulle ou non.

--should return all 4 records
select * from #Temp 
where ClientID = 1 and 
(@FeatureID IS NULL OR FeatureID = @FeatureID)


1 commentaires

Merci @kicken, je dois les combiner en une seule requête, ce n'était qu'un exemple. Est-ce possible?



2
votes

Une formulation alternative qui pourrait être un peu plus simple:

select * from #Temp 
where ClientID = 1 and 
(ISNULL(@FeatureID, FeatureID) = FeatureID or FeatureID is NULL)

Si @FeatureID est nul, alors FeatureID = FeatureID , qui est toujours vrai. Sinon, il recherchera @FeatureID = FeatureID .

Il retournera toujours les lignes où FeatureID est nul.


0 commentaires

1
votes

Si vous souhaitez les combiner, cela devrait fonctionner:

select * from #Temp 
where ClientID = 1 and 
(@FeatureID is null
or
(@FeatureID is not null 
    and (FeatureID is null or FeatureID=@FeatureID)))

Cela sélectionnera tous les enregistrements lorsque @FeatureID = null et renverra 2 résultats {(1, null), (1, 1)} quand @FeatureID = 1


0 commentaires