grouper des champs suivant une condition

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

31 mai 2005, 15:34

Bonjour,

j'ai un petite table table1 (j'allège la structure pour l'exemple)

Code : Tout sélectionner

id int date1 date date2 date
je souhaiterais grouper les résultats sur une condition, directement dans MySQL pour éviter un traitement lourd en PHP

catégories :
DATEDIFF(date1,date2) <= 7 (-->"DM" Dernière Minute)
DATEDIFF(date1,date2) <= 15 (-->"SP" Semaine Prochaine)
DATEDIFF(date1,date2) <= 30 (-->"SS" Semaine Suivante)

afin d'obtenir directement comme résultat :
le nombre d'enregistrements de chaque catégorie du genre
5 DM
7 SP
2 SS

est-il possible de créer un champ "perso" (ici catégorie) et de lui donner une valeur suivant la condition ?
dans l'idée de faire un COUNT(id) avec un GROUP BY "catégorie"

j'ai regardé du coté de IF et de CASE, mais je ne sais pas si ça peut s'utiliser au milieu d'une requête et surtout pour donner une valeur à un champ "perso"

je ne sais pas si c'est très clair comme explication, mais si ce que je veux l'est, les possibilités de le faire ne le sont pas donc j'ai un peu de mal :lol:

Donc si quelqu'un à une piste à suggérer, ou souhaite des précisions... nhésitez pas ;)

Merci

Modérateur PHPfrance
Modérateur PHPfrance | 6037 Messages

01 juin 2005, 22:36

Ton problème a l'air très intéressant et j'aimerais bien t'aider, mais je n'ai pas tout compris.

Je récapitule :
  1. tu as une table dans une BDD
  2. tu souhaites faire une requête dessus
  3. cette requête demande un classement des champs (order by)
  4. et aussi plusieurs conditions
  5. qui découlent parfois d'une condition précédente (si a>b, prendre tous les z>y)
Si j'ai mal compris, dis moi sur quel point.

Un 1er élément de réponse : non, un if/else PHP en plein milieu de requête paraît peu utilisable. Et puis, il faut avoir les résultats dans le PHP pour faire un traitement.[/color]
Règle n°2 du webmaster : Toujours commencer par le HTML qu'on veut obtenir....toujours ! :priere:
J'aime apprendre de nouvelles choses.

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

02 juin 2005, 08:57

en fait lors de la requête, je souhaiterais faire un calcul (un écart entre deux dates) et suivant cet écart, faire une sorte de flag (c'est ce que j'appelais champ perso) correspondant à la catégorie

car j'ai 4 catégories correspondant à des plages de valeurs pour les écarts :

écart <= 7 -> "DM" (dernière minute)
écart <= 15 -> "SP" (semaine prochaine)
écart <= 30 -> "SS" (semaine suivante)
écart > 30 -> "MS" (mois suivant)

donc je voudrais faire ce classement directement dans la requête, pour grouper par catégorie (par flag) et faire un COUNT(*) sur la catégorie

plutôt que de sortir tous les enregistrements, et pour chaque calculer l'écart et incrémenter un compteur de catégorie

j'espère que c'est un peu plus clair, je n'ai donc qu'un seul test, qui peut donner 4 résultats différent

dans l'absolu la question est :
peut-on créer un "flag" dans le jeu de résultat, dont on attribue la valeur suivant un calcul sur d'autres champs
et de compter ensuite les occurences de chaque catégories

je suis intéressé de savoir ça, même si la question ne s'applique plus pour la tâche que j'ai à réaliser car je me suis rendu compte que les champs contenant des dates sont en VARCHAR :cry: :cry: :cry:

voilà j'espère avoir été un peu plus clair merci :)

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

02 juin 2005, 09:05

un exemple vaut mieux qu'un long discours

la table :
id | dateDeb | dateFin | (écart)

Code : Tout sélectionner

1 | 2005-10-12 | 2005-10-14 | (2) 2 | 2005-10-05 | 2005-10-30 | (25) 3 | 2005-10-07 | 2005-10-11 | (4) 4 | 2005-10-01 | 2005-10-15 | (14)
ce que j'aimerais pouvoir obtenir à l'issue de ma requête

nbre | catégorie

Code : Tout sélectionner

2 | DM 1 | SP 1 | SS 0 | MS

Mammouth du PHP | 19672 Messages

02 juin 2005, 09:52

je me suis rendu compte que les champs contenant des dates sont en VARCHAR ...
Effectivement, ça pose un problème puisque DATEDIFF ne fonctionne que sur des champs DATE ou DATETIME.

D'autre part, DATEDIFF() est disponible depuis MySQL 4.1.1 seulement.

Enfin, le problème est qu'on fait SELECT DATEDIFF(), mais je ne crois pas qu'on puisse faire SELECT COUNT(DATEDIFF()). Donc on doit préciser deux dates prises dans une ligne précise.

Alors est-ce qu'on peut faire SELECT COUNT(*) WHERE DATEDIFF() > x AND DATEDIFF() < y ? Je cherche de mon coté, la question m'intéresse aussi :)
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

02 juin 2005, 11:30

Effectivement, ça pose un problème puisque DATEDIFF ne fonctionne que sur des champs DATE ou DATETIME.
Je ne te le fais pas dire !! :cry:
D'autre part, DATEDIFF() est disponible depuis MySQL 4.1.1 seulement.
ah bon, ben ça règle définitivement le problème, ici c'est du MySQL 3

mais bon, just for fun, si quelqu'un à la réponse/solution pour faire ce classement, je suis ouvert :)

Mammouth du PHP | 19672 Messages

02 juin 2005, 12:13

Au lieu de DATEDIFF, tourne toi vers INTERVAL qui est accepté depuis MySQL 3.23, jette un coup d'oeil ICI
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

02 juin 2005, 12:35

c'est gentil, mais tu as oublié que mes champs sont de type VARCHAR !! :wink:

Mammouth du PHP | 19672 Messages

02 juin 2005, 12:35

Alors fais un CAST pour les traiter comme des dates
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

02 juin 2005, 12:41

j'avais regardé du coté de Cast() et Convert(), mais je n'ai rien vu qui laissait penser que l'on pouvait convertir une chaine vers une date

tu crois que c'est possible ?

si je lis bien, Cast ne sert que sur les types suivants :
BINARY, CHAR, DATE, DATETIME, SIGNED {INTEGER}, TIME, UNSIGNED {INTEGER}

Mammouth du PHP | 19672 Messages

02 juin 2005, 12:51

Non, en fait, je viens de voir autre chose qui ruine l'idée:
CAST() et CONVERT() sont disponibles depuis MySQL 4.0.2.
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

ViPHP
pjl
ViPHP | 2119 Messages

03 juin 2005, 18:44

c'est gentil, mais tu as oublié que mes champs sont de type VARCHAR !! :wink:
et pourquoi ne pas mettre le champ au format date ?

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

04 juin 2005, 11:46

héhé je l'attendais celle là et ça m'étonne qu'elle ne soit pas venue plus tôt :lol:

tout simplement parceque je suis en stage, et que la base est utilisée et bien remplie
donc je fais avec ce que j'ai ;)

ViPHP
pjl
ViPHP | 2119 Messages

04 juin 2005, 11:52

et alors, ou est le problème ?
Tu vas voir ton maitre de stage et tu lui dis.

Si demain, je dois faire un stage en menuiserie et que l'on me file un tournevis droit pour visser des vis à empreinte philips, j'irai voir mon maitre de stage pour lui dire que je ne peux pas viser avec ce tournevis là, je lui expliquerai les inconvéniants (déformation de la tête de la vis, vis pas assez serrée) et les solutions (pret ou achat d'un tournevis cruciforme).

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

04 juin 2005, 11:59

tu rigoles ou quoi

faut pas exagérer
je l'ai fait remarquer, j'ai dit que mon code était super lourd du fait que tous les tris étaient en PHP

maintenant, penses-tu vraiment que je peux aller le voir au bout d'une semaine et lui dire :
"les champs là ne sont pas du bon type, il faut les passer en Date car ce sera plus pratique pour moi et pour vous
oui bon forcément ça veut dire qu'il faut reprendre tous les scripts, changer les insertions, virer les conversions bref reprendre un peu mais bon c'est l'affaire d'un bon mois rien de plus"

ah oui c'est une appli liée au tourisme, donc qui utilise plein de dates

alors franchement ce que tu me dis de faire n'est pas réaliste

je lui ai dit, je lui ai expliqué ce que j'en pensais, maintenant eux préfèrent les varchar, il n'a pas v raiment donné de justification et il n'y en a pas
mais je ne peux pas changer toute l'appli, c'est fait c'est fait...

changer de tournevis ok c'est pas long, mais là il faut plutôt changer toutes les vis pour coller au tournevis que j'ai et ça, ça n'est pas possible ;)