Je sais que plusieurs paramètres peuvent être passés à COALESCE
, mais lorsque vous voulez vérifier une seule expression pour voir si elle n'existe pas, utilisez-vous une valeur par défaut ou est-ce une meilleure pratique d'utiliser ISNULL
à la place?
Y a-t-il un gain de performances entre les deux?
Ce problème signalé sur Microsoft Connect révèle quelques différences entre COALESCE
et ISNULL
:
une première partie de notre traitement réécrit
COALESCE( expression1, expression2 )
enCASE WHEN expression1 IS NOT NULL THEN expression1 ELSE expression2 END
. Dans [cet exemple]:COALESCE ( ( SELECT Nullable FROM Demo WHERE SomeCol = 1 ), 1 )
nous générons:
SELECT CASE WHEN (SELECT Nullable FROM Demo WHERE SomeCol = 1) IS NOT NULL THEN (SELECT Nullable FROM Demo WHERE SomeCol = 1) ELSE 1 END
Les étapes ultérieures du traitement des requêtes ne comprennent pas que les deux sous-requêtes étaient à l'origine la même expression, elles exécutent donc la sous-requête deux fois ...
Une solution de contournement, bien que je déteste le suggérer, consiste à remplacer
COALESCE
parISNULL
, car ce dernier ne fait pas double emploi avec la sous-requête.
Je ne pense pas, mais COALESCE est dans la norme SQL '92 et supporté par des bases de données plus différentes. Si vous optez pour la portabilité, n'utilisez pas ISNULL.
Il convient de mentionner que la gestion des types entre les deux peut également faire une différence (voir cet élément de réponse connexe (2) ).
Supposons qu'une requête tente d'utiliser un raccourci pour écrire une comparaison nulle:
select * from SomeTable
where IsNull(SomeNullableBitField, -1) != IsNull(SomeOtherNullableBitField, -1);
qui est différent de
select * from SomeTable
where coalesce(SomeNullableBitField, -1) != coalesce(SomeOtherNullableBitField, -1);
Parce que dans le premier cas, IsNull () force le type à être un peu (donc -1 est converti en vrai) tandis que le second cas promouvra les deux en int.
with input as
(
select convert(bit, 1) as BitOn,
convert(bit, 0) as BitOff,
convert(bit, null) as BitNull
)
select BitOn,
BitOff,
BitNull,
IsNull(BitOn, -1) IsNullBitOn, -- true
IsNull(BitOff, -1) IsNullBitOff, -- false
IsNull(BitNull, -1) IsNullBitNull, -- true, converts the -1 to bit
coalesce(BitOn, -1) CoalesceBitOn, -- 1
coalesce(BitOff, -1) CoalesceBitOff, -- 0
coalesce(BitNull, -1) CoalesceBitNull -- -1
from input;
Il existe un commentaire/lien similaire (@Martin Smith) sur la question elle-même.
Une chose importante que je ne vois pas explicitement indiquée est que le type de sortie de ISNULL
est similaire à la première expression mais avec COALESCE
il retourne le type de données de la valeur de la plus haute priorité.
DECLARE @X VARCHAR(3) = NULL
DECLARE @Y VARCHAR(10) = '123456789'
/* The datatype returned is similar to X, or the first expression*/
SELECT ISNULL(@X, @Y) ---> Output is '123'
/* The datatype returned is similar to Y, or to the value of highest precedence*/
SELECT COALESCE(@X, @Y) ---> Output is '123456789'
Cette explication donne clairement sur coalesce vs isnull
La fonction COALESCE dans SQL renvoie la première expression non NULL parmi ses arguments. La syntaxe de COALESCE est la suivante:
COALESCE ("expression 1", "expressions 2", ...)
C'est la même chose que l'instruction CASE suivante:
SELECT CASE ("column_name")
WHEN "expression 1 is not NULL" THEN "expression 1"
WHEN "expression 2 is not NULL" THEN "expression 2"
...
[ELSE "NULL"]
END
FROM "table_name";
Dans SQL Server, la fonction ISNULL () est utilisée pour remplacer la valeur NULL par une autre valeur.
select CountryName = ISNULL("columnname", 'INDIA') from Countries
Coalesce renvoie la première expression non nulle où as isull () est utilisé pour remplacer la valeur nulle par notre valeur souhaitée.
COALESCE fait partie des normes ANSI et est disponible dans presque toutes les bases de données.
lors du choix entre ISNULL v COALESCE, les paramètres doivent être pris en compte:
Envisagez de suivre les instructions SQL
DECLARE @c5 VARCHAR(5);
SELECT 'COALESCE', COALESCE(@c5, 'longer name')
UNION ALL
SELECT 'ISNULL', ISNULL(@c5, 'longer name');
Résultats:
COALESCE longer name
ISNULL longe
Cela se produit car ISNULL prend le type de données du premier argument, tandis que COALESCE inspecte tous les éléments et choisit le meilleur ajustement (dans ce cas, VARCHAR (11))
Pour une explication plus détaillée sur la décision entre COALESCE vs ISNULL, vérifiez ceci: https://www.mssqltips.com/sqlservertip/2689/deciding-between-coalesce-and-isnull-in-sql-server/
Lorsqu'il n'y a qu'une seule condition nulle, ISNULL
aura moins de surcharge. Cependant, la différence est probablement négligeable.
NULL
et COALESCE
ne sont pas toujours interchangeables. Il mérite de connaître leurs différences afin de savoir quand il vaut mieux utiliser l'un sur l'autre:
Le tableau ci-dessus est une comparaison entre ISNULL
et COALESCE
du livre Exam Ref 70-761 Querying Data with Transact-SQL
Écrit par Itzik Ben-Gan.
2
Pour ISNULL
vs >2
Lors de l'utilisation de COALESCE
ISNULL
est une fonctionnalité T-SQL propriétaire et COALESCE
est la norme SQL ISO/ANSILe type de données du résultat est important. Après avoir lu les notes du tableau ci-dessus, vérifiez les cas suivants:
DECLARE @x VARCHAR(3) = NULL
,@y VARCHAR(10) = '1234567890';
SELECT ISNULL(@x, @y) AS [ISNULL], COALESCE(@x, @y) AS [COALESCE];
ISNULL
obtient le type de données du premier argument car c'est le littéral non NULL
. Il s'agit de VARCHAR(3)
et est un résultat, les données du deuxième argument sont coupées pour y correspondre. Avec COALESCE
le type de données si la priorité la plus élevée est utilisée.
DECLARE @x VARCHAR(8) = '123x5'
,@y INT = 123;
SELECT ISNULL(@x, @y) AS [ISNULL];
SELECT COALESCE(@x, @y) AS [COALESCE];
ISNULL
renvoie le type de données du premier argument, tandis que dans COALESCE
, nous obtenons une erreur, car INT
a la priorité la plus élevée et la conversion de la première valeur d'argument en INT
échoue.
La nullité du résultat peut également être importante. Par exemple:
DECLARE @x VARCHAR(3) = NULL
,@y VARCHAR(3) = NULL;
DROP TABLE IF EXISTS [dbo].[DataSource01];
SELECT ISNULL(10, 20) AS [C1]
,ISNULL(@x, 'text') AS [C2]
,ISNULL(@x, @y) AS [C3]
INTO [dbo].[DataSource01];
DROP TABLE IF EXISTS [dbo].[DataSource02];
SELECT COALESCE(10, 20) AS [C1]
,COALESCE(@x, 'text') AS [C2]
,COALESCE(@x, @y) AS [C3]
INTO [dbo].[DataSource02];
Vérifions la propriété Nullable
de chaque colonne:
En utilisant COALESCE
, nous avons une propriété NOT NULL
De colonne définie sur Yes
, uniquement lorsque toutes les entrées ne sont pas nulles.
Selon le standard SQL, l'expression COALESCE
est traduite en:
CASE WHEN (<subquery>) IS NOT NULL THEN (<subquery>) ELSE 0 END
Si le résultat de l'exécution de la sous-requête dans la clause WHEN n'est pas NULL, SQL Server l'exécute une deuxième fois dans la clause THEN. En d'autres termes, dans un tel cas, il l'exécute deux fois. Ce n'est que si le résultat de l'exécution dans la clause WHEN est NULL que SQL Server n'exécute plus la sous-requête, mais renvoie plutôt l'expression ELSE. Ainsi, lorsque vous utilisez des sous-requêtes, la fonction ISNULL présente un avantage en termes de performances.