banniere

Le portail francophone de la géomatique


Toujours pas inscrit ? Mot de passe oublié ?
Nom d'utilisateur    Mot de passe              Toujours pas inscrit ?   Mot de passe oublié ?

#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

p.jeremie a écrit:

utiliser un éditeur de texte [...] par exemple Notepad++


+1 comme on dit wink

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

Dizzy84 a écrit:

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

 

Pied de page des forums

Powered by FluxBB