Pages: 1
- Sujet précédent - Help! syntaxe SQL "case-when-else" in Gestionnaire BD QGIS 3.18.1 - Sujet suivant
#1 Fri 26 March 2021 18:41
- Dizzy84
- Participant occasionnel
- Date d'inscription: 20 Jun 2012
- Messages: 10
Help! syntaxe SQL "case-when-else" in Gestionnaire BD QGIS 3.18.1
Bonjour,
je bloque sur une syntaxe sql qui me retourne toujours l'erreru suivante :
- syntaxe error near Case
Voilà mon code pourtant pas si complexe, pour lequel j'attend la création d'un nouveau champ qui prendrait les valeurs 1,2,3,4, etc.:
Pour traduire, le but est une discretisation en classes d'égales amplitude.
Merci d'avance !
SELECT
"Distance","Var","geometry"
CASE
WHEN "Distance" < (Min("Distance")+(1*((max("Distance")-min("Distance"))/19)) THEN '1'
WHEN "Distance" < (Min("Distance")+(2*((max("Distance")-min("Distance"))/19)) THEN '2'
WHEN "Distance" < (Min("Distance")+(3*((max("Distance")-min("Distance"))/19)) THEN '3'
WHEN "Distance" < (Min("Distance")+(4*((max("Distance")-min("Distance"))/19)) THEN '4'
WHEN "Distance" < (Min("Distance")+(5*((max("Distance")-min("Distance"))/19)) THEN '5'
WHEN "Distance" < (Min("Distance")+(6*((max("Distance")-min("Distance"))/19)) THEN '6'
WHEN "Distance" < (Min("Distance")+(7*((max("Distance")-min("Distance"))/19)) THEN '7'
WHEN "Distance" < (Min("Distance")+(8*((max("Distance")-min("Distance"))/19)) THEN '8'
WHEN "Distance" < (Min("Distance")+(9*((max("Distance")-min("Distance"))/19)) THEN '8'
WHEN "Distance" < (Min("Distance")+(10*((max("Distance")-min("Distance"))/19)) THEN '10'
WHEN "Distance" < (Min("Distance")+(11*((max("Distance")-min("Distance"))/19)) THEN '11'
WHEN "Distance" < (Min("Distance")+(12*((max("Distance")-min("Distance"))/19)) THEN '12'
WHEN "Distance" < (Min("Distance")+(13*((max("Distance")-min("Distance"))/19)) THEN '13'
WHEN "Distance" < (Min("Distance")+(14*((max("Distance")-min("Distance"))/19)) THEN '14'
WHEN "Distance" < (Min("Distance")+(15*((max("Distance")-min("Distance"))/19)) THEN '15'
WHEN "Distance" < (Min("Distance")+(16*((max("Distance")-min("Distance"))/19)) THEN '16'
WHEN "Distance" < (Min("Distance")+(17*((max("Distance")-min("Distance"))/19)) THEN '17'
WHEN "Distance" < (Min("Distance")+(18*((max("Distance")-min("Distance"))/19)) THEN '18'
ELSE '19'
END
FROM "TableVario"
Hors ligne
#2 Fri 26 March 2021 21:45
- Sylvain M.
- Participant assidu
- Lieu: Saint-Pierre-des-Nids (53)
- Date d'inscription: 8 Sep 2005
- Messages: 995
Re: Help! syntaxe SQL "case-when-else" in Gestionnaire BD QGIS 3.18.1
Ne manquerait-il simplement pas une virgule entre "geometry" et CASE ?
PS. : et sinon, attention, il y a 2x "THEN '8'" et pas de "THEN '9'"
Dernière modification par Sylvain M. (Fri 26 March 2021 21:50)
Sylvain M.
Hors ligne
#3 Sun 28 March 2021 15:07
- Dizzy84
- Participant occasionnel
- Date d'inscription: 20 Jun 2012
- Messages: 10
Re: Help! syntaxe SQL "case-when-else" in Gestionnaire BD QGIS 3.18.1
trop fort, merci.
j'ai corrigé mais il reste une erreur qui là aussi me laisse perplexe:
"near "THEN": syntax error"
pourtant il n'y a pas de virugule dans la syntaxe when then else, non?
je suis preneur de toutes suggestion,
merci d'avance.
le code avec les corrections de Sylvain est maintenant:
SELECT
"Distance","Var","geometry",
CASE
WHEN "Distance" < (Min("Distance")+(1*((max("Distance")-min("Distance"))/19)) THEN '01'
WHEN "Distance" < (Min("Distance")+(2*((max("Distance")-min("Distance"))/19)) THEN '02'
WHEN "Distance" < (Min("Distance")+(3*((max("Distance")-min("Distance"))/19)) THEN '03'
WHEN "Distance" < (Min("Distance")+(4*((max("Distance")-min("Distance"))/19)) THEN '04'
WHEN "Distance" < (Min("Distance")+(5*((max("Distance")-min("Distance"))/19)) THEN '05'
WHEN "Distance" < (Min("Distance")+(6*((max("Distance")-min("Distance"))/19)) THEN '06'
WHEN "Distance" < (Min("Distance")+(7*((max("Distance")-min("Distance"))/19)) THEN '07'
WHEN "Distance" < (Min("Distance")+(8*((max("Distance")-min("Distance"))/19)) THEN '08'
WHEN "Distance" < (Min("Distance")+(9*((max("Distance")-min("Distance"))/19)) THEN '09'
WHEN "Distance" < (Min("Distance")+(10*((max("Distance")-min("Distance"))/19)) THEN '10'
WHEN "Distance" < (Min("Distance")+(11*((max("Distance")-min("Distance"))/19)) THEN '11'
WHEN "Distance" < (Min("Distance")+(12*((max("Distance")-min("Distance"))/19)) THEN '12'
WHEN "Distance" < (Min("Distance")+(13*((max("Distance")-min("Distance"))/19)) THEN '13'
WHEN "Distance" < (Min("Distance")+(14*((max("Distance")-min("Distance"))/19)) THEN '14'
WHEN "Distance" < (Min("Distance")+(15*((max("Distance")-min("Distance"))/19)) THEN '15'
WHEN "Distance" < (Min("Distance")+(16*((max("Distance")-min("Distance"))/19)) THEN '16'
WHEN "Distance" < (Min("Distance")+(17*((max("Distance")-min("Distance"))/19)) THEN '17'
WHEN "Distance" < (Min("Distance")+(18*((max("Distance")-min("Distance"))/19)) THEN '18'
ELSE '19'
END
FROM "TableVario"
Dernière modification par Dizzy84 (Sun 28 March 2021 15:08)
Hors ligne
#4 Sun 28 March 2021 15:18
- Sylvain M.
- Participant assidu
- Lieu: Saint-Pierre-des-Nids (53)
- Date d'inscription: 8 Sep 2005
- Messages: 995
Re: Help! syntaxe SQL "case-when-else" in Gestionnaire BD QGIS 3.18.1
Je n'ai pas encore cherché à comprendre ta formule, mais déjà pour identifier le problème, tu peux t'arrêter à 2 conditions:
Code:
case when condition1 then valeur1 else when condition2 then valeur2 else valeur3
Ce sera plus facile d'identifier le problème.
Personnellement, j'écris toujours "else" après chaque condition.
Reposte ton code avec 2 conditions, et mets le entre balises "code" ce sera plus lisible.
A+
Dernière modification par Sylvain M. (Sun 28 March 2021 15:20)
Sylvain M.
Hors ligne
#5 Sun 28 March 2021 15:23
- Dizzy84
- Participant occasionnel
- Date d'inscription: 20 Jun 2012
- Messages: 10
Re: Help! syntaxe SQL "case-when-else" in Gestionnaire BD QGIS 3.18.1
ok, merci de ton assistance précieuse.
J'ai appliqué la consigne, l'erreur reste la même:
Code:
SELECT "Distance","Var","geometry", CASE WHEN "Distance" < (Min("Distance")+(1*((max("Distance")-min("Distance"))/19)) THEN '01' else WHEN "Distance" < (Min("Distance")+(2*((max("Distance")-min("Distance"))/19)) THEN '02' ELSE '19' END FROM "TableVario"
est-ce que le problème viendrait d'un effet de boucle dans la formule?
En gros, j'ai un champ distance que je veux regrouper en classes d'égale amplitude.
Donc je prends l'amplitude de mon champ distance (max distance - min distance) que je divise en 19 classes (nombre de classe choisi arbitrairement) pour avoir l'amplitude de chaque classe.
Puis je cherche à avoir la borne supérieure de chaque classe et à vérifier que la valeur de mon champ distance soit bien en-dessous pour la "classer" dans la classe en question.
Pour trouver la borne supérieure de chaque classe, je prend la valeur minimum de la distribution (min(distance)) à laquelle j'additionne, d'abord 1 fois l'amplitude de la classe (borne supérieure de la classe 1) puis 2 fois l'amplitude de la classe (borne superieure de la classe 2), etc. jusqu'à 18, le reste étant dans la classe 19.
Dernière modification par Dizzy84 (Sun 28 March 2021 15:28)
Hors ligne
#6 Sun 28 March 2021 20:44
- p.jeremie
- Participant assidu
- Lieu: Valence
- Date d'inscription: 10 Sep 2017
- Messages: 427
Re: Help! syntaxe SQL "case-when-else" in Gestionnaire BD QGIS 3.18.1
Il manque des parenthèses fermantes dans tes WHEN.
En détaillant le code par ligne et en indentant on peut mieux voir où.
Code:
SELECT "Distance","Var","geometry", CASE WHEN "Distance" < ( Min("Distance") + (1* ( ( max("Distance") - min("Distance") ) /19 ) ) // ici il manque une parenthèse fermante THEN '01' else WHEN "Distance" < ( Min("Distance") + (2* ( ( max("Distance") - min("Distance") ) /19 ) ) // ici il manque une parenthèse fermante THEN '02' ELSE '19' END FROM "TableVario"
Ou sinon, utiliser un éditeur de texte qui te fait voir à quelle parenthèse ouvrante correspond une parenthèse fermante et inversement (par exemple Notepad++).
Ou simplement, compter le nombre de parenthèses ouvrantes et fermantes, s'il y en a moins d'une sorte, c'est qu'il en manque de cette sorte.
Hors ligne
#7 Sun 28 March 2021 20:57
- Sylvain M.
- Participant assidu
- Lieu: Saint-Pierre-des-Nids (53)
- Date d'inscription: 8 Sep 2005
- Messages: 995
Re: Help! syntaxe SQL "case-when-else" in Gestionnaire BD QGIS 3.18.1
utiliser un éditeur de texte [...] par exemple Notepad++
+1 comme on dit
Et sinon, après ton "END", tu peux ajouter un "AS nom_du_champ" pour donner un nom au champ que tu crées.
Dernière modification par Sylvain M. (Sun 28 March 2021 20:59)
Sylvain M.
Hors ligne
#8 Mon 29 March 2021 04:41
- Dizzy84
- Participant occasionnel
- Date d'inscription: 20 Jun 2012
- Messages: 10
Re: Help! syntaxe SQL "case-when-else" in Gestionnaire BD QGIS 3.18.1
Ok, super merci à tous les deux.
Mazette j'aurais dû le voir...
Bon, les difficultés sont... presque terminées.
En effet, le résultat en sortie ne fait qu'une seule ligne.... Bien entendu, j'aurais souhaité que pour chaque ligne de ma base initiale, il affecte la valeur 1 ou 2 ou 3,... ou 19.
Là il semble qu'à la première ligne, ayant réussit l'opération, il s'arrête.
J'imagine qu'il faut aborder les notions de fonctions intératives ou ce genre de choses (auxquelles je ne suis pas familier)...?
Si vous avez encore le temps d'un petit conseil.
Grand merci d'avance.
Hors ligne
#9 Mon 29 March 2021 12:40
- Sylvain M.
- Participant assidu
- Lieu: Saint-Pierre-des-Nids (53)
- Date d'inscription: 8 Sep 2005
- Messages: 995
Re: Help! syntaxe SQL "case-when-else" in Gestionnaire BD QGIS 3.18.1
En effet, j'ai testé, j'ai le même comportement.
Les formules "min" et "max" sont des formules d’agrégation SQL, du coup, il faut les appeler dans des requêtes d'agrégation.
Pour cela, il suffit de remplacer tous tes
Code:
max("Distance")
par
Code:
SELECT max("Distance") FROM "TableVario"
Je ne suis pas expert en SQL, mais je pense que ce serait plus facile avec une requête de type "WITH" avant (cf. CTE SQL sur Google) :
Code:
WITH stats AS (SELECT max("Distance") as maxdist, min("Distance") as mindist FROM "TableVario")
Sylvain M.
Hors ligne
#10 Mon 29 March 2021 12:48
- Sylvain M.
- Participant assidu
- Lieu: Saint-Pierre-des-Nids (53)
- Date d'inscription: 8 Sep 2005
- Messages: 995
Re: Help! syntaxe SQL "case-when-else" in Gestionnaire BD QGIS 3.18.1
Voici un exemple sur une requête simple :
Code:
WITH stats as (SELECT max(distance) as maxdistance, min(distance) as mindistance FROM MaCouche) SELECT ID, CASE WHEN (distance < stats.maxdistance - stats.mindistance) /2 THEN 'inf' else 'sup' END as diff FROM MaCouche, stats
Dernière modification par Sylvain M. (Mon 29 March 2021 12:49)
Sylvain M.
Hors ligne
#11 Wed 31 March 2021 20:52
- Dizzy84
- Participant occasionnel
- Date d'inscription: 20 Jun 2012
- Messages: 10
Re: Help! syntaxe SQL "case-when-else" in Gestionnaire BD QGIS 3.18.1
génial ! ça fonctionne !
je sais maintenant faire une discretisation par la méthode des amplitudes égales en sql.
Merci à vous !
Hors ligne
#12 Wed 31 March 2021 22:51
- p.jeremie
- Participant assidu
- Lieu: Valence
- Date d'inscription: 10 Sep 2017
- Messages: 427
Re: Help! syntaxe SQL "case-when-else" in Gestionnaire BD QGIS 3.18.1
Belle idée la CTE, c'est exactement ce qu'il faut !
Hors ligne
#13 Thu 01 April 2021 11:09
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1549
Re: Help! syntaxe SQL "case-when-else" in Gestionnaire BD QGIS 3.18.1
génial ! ça fonctionne !
je sais maintenant faire une discretisation par la méthode des amplitudes égales en sql.
Merci à vous !
Bonjour,
Vous pouvez éviter la lourdeur du case et de devoir ecrire les classes explicitement avec les windows functions. ntile() ici: https://www.postgresql.org/docs/13/func … ndow.html.
Ici, 5 classes crées sur le champ distance:
Code:
select id, distance, ntile(5) over (order by distance) as val from macouche; id distance val 1 1 1 5 2.2 1 2 3 2 3 5.5 2 6 6.7 3 7 7 3 8 7.1 4 4 9 4 9 14.4 5 10 15.1 5
Nicolas
Hors ligne
#14 Fri 02 April 2021 01:44
- Dizzy84
- Participant occasionnel
- Date d'inscription: 20 Jun 2012
- Messages: 10
Re: Help! syntaxe SQL "case-when-else" in Gestionnaire BD QGIS 3.18.1
Merci Nicolas,
mais cela ne fait pas la même chose. Je découvre car je ne connaissais pas mais la fonction ntile() semble réaliser des classes d'effectifs égaux, or je chercher à créer des classes d'amplitudes égales.
Cependant je suis aussi tombé sur la fonction partition by qui pourrait peut-être aider.
Pour l'instant je vais me contenter de la proposition de Sylvain qui fonctionne.
Merci à tous
Dernière modification par Dizzy84 (Fri 02 April 2021 01:46)
Hors ligne
Pages: 1
- Sujet précédent - Help! syntaxe SQL "case-when-else" in Gestionnaire BD QGIS 3.18.1 - Sujet suivant