2
votes

CAST, SUM, CASE Problèmes

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  


1 commentaires

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 un varchar '2' est supérieur à '199' et '1' + '2' équivaut à '12' . Vous devriez vraiment corriger votre type de données ici.


5 Réponses :


1
votes

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.


0 commentaires

3
votes

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


0 commentaires

1
votes

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


0 commentaires

1
votes

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 .



0
votes

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

entrez la description de l'image ici

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


2 commentaires

"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 ; 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