8791 sujets

Développement web côté serveur, CMS

Bonjour à tous,

J'ai déjà posté sur un autre forum spécifique à PHP, mais aucune réponse.
En fait, ma table contient deux champs "debut" et "fin". Dans un premier temps, je souhaiterais récupérer toutes les dates encore valides aujourd'hui, et les organiser par date de fin (les données se terminant bientôt arrivant en premier). Je fais donc ceci :

SELECT debut, fin FROM table WHERE debut <= "'.date('Y-m-d').'" AND fin >= "'.date('Y-m-d').'" ORDER BY fin ASC



Jusque là, pas de soucis. Je sais que j'aurais pu utiliser now() mais je tiens à utiliser Php car nous allons nous baser sur plusieurs fuseaux horaires, définis dans la configuration PHP. Ensuite, dans une même requête (car il y aura un LIMIT), je souhaite ensuite récupérer les informations antérieures. En d'autres termes, les données dont la fin a expirée, triée de la plus proche à la plus éloignées. On m'a conseillé de faire un UNION et d'organiser les requêtes avec des alias, comme suit :

(SELECT debut, fin, 1 AS organis FROM table WHERE debut <= "'.date('Y-m-d').'" AND fin >= "'.date('Y-m-d').'" ORDER BY fin ASC) UNION ALL (SELECT debut, fin, 2 AS organis FROM table WHERE fin < "'.date('Y-m-d').'" ORDER BY fin DESC) ORDER BY organis ASC


Et le résultat dans un print_r :

Array
(
    [0] => Array
        (
            [ref_doc] => 1945
            [deb] => 2011-10-24
            [fin] => 2011-11-30
			[organis] => 1
        )

    [1] => Array
        (
            [ref_doc] => 1909
            [deb] => 2011-10-07
            [fin] => 2012-02-28
			[organis] => 1
        )
    [2] => Array
        (
            [ref_doc] => 1412
            [deb] => 2008-01-09
            [fin] => 2008-01-20
			[organis] => 2
        )
    [3] => Array
        (
            [ref_doc] => 1482
            [deb] => 2011-04-09
            [fin] => 2011-04-30
			[organis] => 2
        )
)



Tous les résultats sont bien affichés, cependant ça désorganise les résultats de la seconde requêtes. En fait, lorsque j'utilise l'un ou l'autre select, l'ordre est bien suivis. En revanche, lorsque j'utilise les deux avec des alias, ça me les désorganise.

Quelqu'un saurait-il comment faire ?
Merci d'avance Smiley smile
Modifié par Gaylord.P (24 Nov 2011 - 16:00)
salut

essayes comme ça...

(SELECT debut, fin as fin1, 1 AS organis FROM table WHERE debut <= "'.date('Y-m-d').'" AND fin >= "'.date('Y-m-d').'" ORDER BY fin1 ASC) UNION ALL (SELECT debut, fin as fin2, 2 AS organis FROM table WHERE fin < "'.date('Y-m-d').'" ORDER BY fin2 DESC) ORDER BY organis ASC

je te garanti pas le résultat...

En même temps pourquoi ne pas faire 2 requètes distinctes ??? et assembler les array après ???

voir array_merge
Merci mais ça ne fonctionne pas =S

Je n'utilise pas de array_merge car sur la totalité des résultats, il y a un LIMIT. Smiley smile
Même si c'est vrai que je pourrais compter la totalité des résultats ... mais lorsque le LIMIT ne commence pas à zéro, ça va poser problème =S
hum, oui mais les LIMIT c'est pour de la pagination?

si oui j'imagine que chaque page a un nombre raisonnable d'éléments par page?

je te dirais bien tri tous les résultats dans le même ordre. du coup ils seront ordonnés

ORDER BY organis,fin ASC

puis LIMIT

puis re-tri tous les éléments ou organis vaut 2. bouclage sur le tableau , tableau temporaire , ré-injection.

bon c'est crade mais franchement si tu as 25 ou 100 éléments par page c'est pas ça qui va tué ton serveur.
Merci de ta réponse mais j'ai réellement du mal à comprendre le principe .. =/

Sinon oui, c'est pour de la pagination. Avec 12 à 24 résultats par page, ça dépend.

Merci d'avance Smiley smile
Salut,

Oui à la réflexion ça ne marchait pas.

par contre j'ai un peu plus d'espoir avec ce qui suit, je l'ai testé mais avec un jeu de test restreint

j'ai utilisé des now() (plus simple pour tester). et j'ai mis dans ma requête '1970-01-01' avec l'idée de représenté la date la plus petite possible. (en fait ça doit dépendre du type de tes dates)

(
SELECT debut, fin AS fin1, '1970-01-01' AS fin2, 1 AS organis
FROM `table` 
WHERE debut <= now( ) 
AND fin >= now( ) 
)
UNION ALL (

SELECT debut, '1970-01-01' AS fin2, fin AS fin1, 2 AS organis
FROM `table` 
WHERE fin < now( ) 
)
ORDER BY organis ASC , fin1 ASC , fin2 DESC 


ensuite pour avoir fin faut prendre dynamiquement fin1 ou fin2 en fonction de organis
Modifié par CPascal (23 Nov 2011 - 20:20)
Ah oui, pas bête ! Solution simple et très propre !

A priori ça fonctionne, je viens d'essayer et c'est nickel. Je vais tester avec plusieurs requêtes successives (j'ai volontairement simplifié ici) mais ça me semble bon. Smiley smile

Encore merci ! Smiley smile
Cool!

par contre en me relisant j'ai eu des sueurs froides.

Après quelques tests il est clair que le nom des AS du 2eme SELECT ne sert a rien. sinon il aurait fallu inversé fin1 et fin2.

C'est l'ordre d'apparition dans la requête qui compte

on peut même écrire le order by ainsi

ORDER BY 3 ASC , 1 ASC , 2 DESC

les chiffres sont l'ordre d'apparition dans le select et c'est moins ambigüe

Pascal