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
varcharen 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.