J'essaie de tenir compte de certaines valeurs non fiables dans ma base de données, qui contiennent la chaîne «inconnu», je veux les mettre à 0, puis additionner le reste. Mais pour une raison quelconque, cela ne se produit pas. Voici ce que j'ai -
Valeurs - VARCHAR (30) -
Cast(sum(case when stake = 'Unknown' then 0 else stake end) as float) as totalStake
Et voici mon Cast, Sum, Case
3 0.1 2 16 2 5 2 Unknown 2.4 7 Unknown
5 Réponses :
Vous devez explicitement convertir en une sorte de valeurs numériques. Essayez ceci:
sum(try_convert(numeric(18, 4), stake)) as totalStake
Votre code présente au moins deux problèmes. Tout d'abord, votre expression case
renvoie un entier (car le premier puis
a un entier). Donc, il essaie de convertir mise
en un entier, ce qui peut générer une erreur.
Deuxièmement, vous devriez faire des opérations arithmétiques sur des données qui sont explicitement em > une sorte de type de nombre et ne repose pas sur une conversion implicite.
Vous devez lancer la mise en tant que flottant:
sum(case when stake = 'Unknown' then 0.0 else cast(stake as float) end) as totalStake
La première étape serait de remplacer la chaîne "Inconnu" par 0 en utilisant une fonction de remplacement, puis de convertir le type de données de la colonne en celui qui permet d'exécuter des fonctions d'agrégation, puis d'effectuer SOMME en plus de cela. La requête ci-dessous ne fonctionnera que pour la chaîne «inconnue», si vous avez des chaînes différentes autres que «inconnue», vous devrez peut-être choisir une approche différente, comme utiliser IsNumeric dans la fonction Remplacer et mettre à jour la valeur de la chaîne à 0.
select sum(cast((REPLACE(stake,'unknown',0)) as float)) from table
Vous pouvez essayer la requête suivante en utilisant i snumeric ()
pour vérifier les données numériques.
Select SUM(TRY_CAST(stake as Float)) from temp
Pour gérer une exception comme null
valeurs ou .
valeurs que vous pouvez essayer
create table temp (stake VARCHAR(30)) insert into temp values ('3'), ('0.1'), ('2'), ('16'), ('2'), ('5'), ('2'), ('Unknown'), ('2.4'), ('7'), ('Unknown') --Select * from temp Select sum(Cast(stake as Float)) from temp where isnumeric(stake) = 1
Vous pouvez trouver la démo en direct Ici .
Je déconseille isnumeric
. Étant donné que l'OP a des valeurs comme 'Inconnu'
dans une colonne qui est censée avoir des données numériques, je ne le placerais pas au-delà d'eux pour avoir des valeurs comme '.'
; ce qui provoquera une erreur SQL. TRY_CONVERT
et TRY_CAST
sont des fonctions beaucoup plus fiables. ISNUMERIC
peut fournir et fournit de mauvaises réponses.
@Larnu mais U vous ne pouvez pas insérer Inconnu dans une autre colonne de type de données.
"ce qui provoquera une erreur SQL." @Larnu voir ceci a> Je ne vois pas d'erreur SQL Server 2017 lors de l'utilisation de isnumeric ("Unknown")
Oui, car l'OP devrait utiliser NULL
pour représenter une "valeur inconnue". C'est exactement ce qu'est un NULL
.
"l'OP devrait utiliser NULL pour représenter une" valeur inconnue ". C'est exactement ce qu'est un NULL." @Larnu sur lequel je suis d'accord
@RaymondNijland essayez SELECT CASE ISNUMERIC ('.') WHEN 1 THEN CONVERT (decimal (12,2), '.') END
ou SELECT CASE ISNUMERIC ('1.0') WHEN 1 THEN CONVERT (int, '1.0') END
Notez ces deux erreurs de retour. Notez également que ISNUMERIC ('')
renvoie 0, cependant, CONVERT (int, '')
renvoie 0
, car la valeur est convertie avec succès . ISNUMERIC
ne signifie pas que la valeur sera (ou ne sera pas) convertie.
@Larnu, je ne pense pas seulement. (point) est une valeur décimale.
@Larnu, d'accord.
Cela se produit parce que SQL rencontre des problèmes lors de la conversion des valeurs décimales en valeurs entières.
En fait, la fonction sum
renvoie des valeurs entières
Je l'ai résolu en utilisant la fonction round sur la variable values1 (désolé pour en utilisant le même nom pour la table et la colonne):
select Cast(sum(case when values1 = 'Unknown' then 0 else round(values1, 2) end) as float)as totalstrike from values1
"Cela se produit car SQL rencontre des problèmes lors de la conversion des valeurs décimales en valeurs entières." SQL Server n'a aucun problème à convertir un décimal
en un int code>; ce qu'il ne peut pas faire est de convertir une représentation
varchar
d'un décimal
en un int
. La raison pour laquelle SUM
renvoie un int
ici (dans la question de l'OP), c'est parce que c'est le type de données renvoyé par l'expression CASE
, et donc SUM
renvoie un int
: SUM (Transact-SQL) - Types de retour .
Oui Peut-être que je me suis mal exprimé, je voulais dire ce que tu dis
Pourquoi stockez-vous des données numériques sous forme de
varchar
en premier lieu? Il y a tellement de problèmes avec le stockage de données numériques que le mauvais type de données. Par exemple, avec unvarchar
'2'
est supérieur à'199'
et'1' + '2'
équivaut à'12'
. Vous devriez vraiment corriger votre type de données ici.