Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1179 connectés 

  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  [MySQL] SELECT une entrée, celle d'avant et celle d'après en 1 fois ?

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[MySQL] SELECT une entrée, celle d'avant et celle d'après en 1 fois ?

n°1726181
darxmurf
meow
Posté le 29-04-2008 à 13:35:39  profilanswer
 

Hello,
 
Y a-t-il moyen en un SELECT de récupérer une entrée de ma base ainsi que cette d'avant et celle d'après ?
 
J'ai une base photos avec :
 
| ID | NOM | DATE | CATEGORIE |
 
je veux sélectionner ma photo et avoir sous le coude le nom de celle d'avant et celle d'après, dans la même catégorie [:paysan]
Je voulais éviter de devoir faire trop de requêtes à la suite pour ne sortir que 3 entrées...
 
Merci


Message édité par darxmurf le 29-04-2008 à 13:38:13

---------------
Des trucs - flickr - Instagram
mood
Publicité
Posté le 29-04-2008 à 13:35:39  profilanswer
 

n°1726185
darxmurf
meow
Posté le 29-04-2008 à 13:41:29  profilanswer
 

EDIT : ID est une clé primaire. Mais les numéros ID ne se suivent pas forcément en fonction de la catégorie


---------------
Des trucs - flickr - Instagram
n°1726191
sielfried
Posté le 29-04-2008 à 13:48:14  profilanswer
 

Si t'as que l'id de la photo sélectionnée comme base, j'vois pas trop d'autre solution que :
 

Code :
  1. SELECT * FROM tofs t WHERE t.id = <id_de_ta_tof>
  2. union
  3. SELECT * FROM tofs pt WHERE pt.category = t.category AND pt.date = (SELECT max(date) FROM tofs WHERE date < t.date)
  4. union
  5. SELECT * FROM tofs nt WHERE nt.category = t.category AND nt.date = (SELECT min(date) FROM tofs WHERE date > t.date)


 
edit: en fait c'est merdique, voir plus bas.


Message édité par sielfried le 29-04-2008 à 14:40:12

---------------
StarCraft Professional Gaming Database | [Ze Topic] Starcraft/BroodWar
n°1726194
darxmurf
meow
Posté le 29-04-2008 à 13:51:41  profilanswer
 

effectivement j'ai un peu fouillé sur le net mais j'ai trouvé que des histoires avec UNION... je vais me tourner de ce côté donc :/
 
J'aurais pensé que MYSQL intègre une fonction de RANGE ou un truc du genre :)
 
Merci de l'info !


---------------
Des trucs - flickr - Instagram
n°1726202
sielfried
Posté le 29-04-2008 à 14:01:34  profilanswer
 

En fait y a probablement bien mieux :
 

Code :
  1. SELECT * FROM tofs t WHERE t.id = <id_de_ta_tof> AND t.date
  2. BETWEEN
  3. (SELECT MAX(date) FROM tofs pt WHERE pt.category = t.category AND pt.date < t.date)
  4. AND
  5. (SELECT MIN(date) FROM tofs nt WHERE nt.category = t.category AND nt.date > t.date)


Message édité par sielfried le 29-04-2008 à 14:01:52

---------------
StarCraft Professional Gaming Database | [Ze Topic] Starcraft/BroodWar
n°1726214
darxmurf
meow
Posté le 29-04-2008 à 14:06:14  profilanswer
 

bon dans tous les cas ça fait 3 requêtes pour trouver 3 photos :)


---------------
Des trucs - flickr - Instagram
n°1726217
sielfried
Posté le 29-04-2008 à 14:07:28  profilanswer
 

Ouais enfin y en avait 5 dans ma première proposition. [:dawa]

Message cité 1 fois
Message édité par sielfried le 29-04-2008 à 14:07:41

---------------
StarCraft Professional Gaming Database | [Ze Topic] Starcraft/BroodWar
n°1726220
darxmurf
meow
Posté le 29-04-2008 à 14:08:13  profilanswer
 

sielfried a écrit :

Ouais enfin y en avait 5 dans ma première proposition. [:dawa]


 
spa faux [:tinostar]


---------------
Des trucs - flickr - Instagram
n°1726265
casimimir
Posté le 29-04-2008 à 14:35:37  profilanswer
 

la première requete marche en mysql? parceque en oracle il me jetterait pour les alias
 
sinon la 2eme requete devrait etre ok mais il faut changer le AND en OR
 

Code :
  1. SELECT *
  2. FROM tofs t
  3. WHERE t.id = <id_de_ta_tof>
  4. OR t.date BETWEEN(SELECT MAX(date) FROM tofs pt WHERE pt.category = t.category
  5.              AND pt.date < t.date)AND(SELECT MIN(date) FROM tofs nt WHERE nt.category = t.category AND nt.date > t.date)

n°1726271
sielfried
Posté le 29-04-2008 à 14:39:33  profilanswer
 

Effectivement, étourderie. [:petrus75]
 
D'ailleurs en fait pas besoin de BETWEEN, juste deux OR avec des =.
 
edit tardif: bon en fait non, ça va pas du tout, t.date n'a aucun sens dans ces conditions.


Message édité par sielfried le 29-04-2008 à 16:45:04

---------------
StarCraft Professional Gaming Database | [Ze Topic] Starcraft/BroodWar
mood
Publicité
Posté le 29-04-2008 à 14:39:33  profilanswer
 

n°1726314
anapajari
s/travail/glanding on hfr/gs;
Posté le 29-04-2008 à 15:27:32  profilanswer
 

Le min/max sur les date est une mauvaise idée: s'il y a plusieurs photos pour une date donnée, la requête plus haut peut potentiellement remonter plus de 3 lignes.

 

Je ferais un truc dans le genre:

Code :
  1. SELECT
  2. case when sign(T1.id - T2.id) > 0 then 'prev'
  3.      when sign(T1.id - T2.id) < 0 then 'next'
  4.      else 'curr' end AS item,
  5. case when sign(T1.id - T2.id) > 0 then max(T2.id)
  6.      when sign(T1.id - T2.id) < 0 then min(T2.id)
  7.      else T1.id end AS item,
  8.      T2.*
  9. FROM
  10. tofs T1
  11. INNER JOIN tofs T2 ON T1.category = T2.category
  12. WHERE  T1.id=<id_de_ta_tof>
  13. GROUP BY T1.id, sign(T1.id - T2.id)
  14. ORDER BY sign(T1.id - T2.id)


note: en plus si les indexes sont correctement réglés celà sera plus rapide ;)
note2: c'est du pur MySQL, ça risque de pas marcher sur autre chose ( en particulier a cause du group by)


Message édité par anapajari le 29-04-2008 à 15:28:53

---------------
Software and cathedrals are much the same - first we build them, then we pray.
n°1726345
sielfried
Posté le 29-04-2008 à 16:16:36  profilanswer
 

Ouais mais il a dit que les IDs étaient pas forcément dans l'ordre je crois. (Enfin en fait non après relecture, c'était ptete pas forcément ce qu'il voulait dire. [:petrus75])
 
Du coup j'ai supposé que ces "dates" étaient des datetime (auquel cas je pense que mon truc fonctionne).


---------------
StarCraft Professional Gaming Database | [Ze Topic] Starcraft/BroodWar
n°1726360
darxmurf
meow
Posté le 29-04-2008 à 16:28:06  profilanswer
 

non en fait ce que je voulais dire c'est que si on fais un select de 3 images de la même cat, les ID ne seront pas forcément ID, ID+1, ID+2  
c'est pour ça qu'une requête avec WHERE ID=t.id-1 n'aurait pas joué :)


---------------
Des trucs - flickr - Instagram
n°1726364
darxmurf
meow
Posté le 29-04-2008 à 16:31:04  profilanswer
 

en passant, j'ai essayé de faire une bête requête  
SELECT MAX(date), name FROM table ... LIMIT 1
et il me retourne qu'il faut mettre un GROUP BY [:paysan] pourquoi ?


---------------
Des trucs - flickr - Instagram
n°1726370
casimimir
Posté le 29-04-2008 à 16:34:06  profilanswer
 

on peut mettre un min ou un max dans un case en mysql(quasi jamais utilisé)?
 
en oracle a la limite on pourrait en utilisant les min/max version fonction analytique, mais la il ralerait direct.

n°1726371
Paulp
~, sweet ~
Posté le 29-04-2008 à 16:34:14  profilanswer
 

darxmurf a écrit :

en passant, j'ai essayé de faire une bête requête  
SELECT MAX(date), name FROM table ... LIMIT 1
et il me retourne qu'il faut mettre un GROUP BY [:paysan] pourquoi ?


SELECT date, name FROM table ORDER BY date DESC LIMIT 1
 
edit : en fait ça répond pas a ta question
 
en fait, il ne sait pas quel name choisir.
Il faudrait faire SELECT date, name FROM table WHERE date=(SELECT max(date) FROM TABLE) je pense


Message édité par Paulp le 29-04-2008 à 16:36:35
n°1726374
sielfried
Posté le 29-04-2008 à 16:34:57  profilanswer
 

edit: j'ai rien dit mon truc marchera jamais, d'ailleurs celles d'au dessus non plus (faut forcément un join ou un union quelque part)

Message cité 1 fois
Message édité par sielfried le 29-04-2008 à 16:44:25

---------------
StarCraft Professional Gaming Database | [Ze Topic] Starcraft/BroodWar
n°1726390
anapajari
s/travail/glanding on hfr/gs;
Posté le 29-04-2008 à 16:51:46  profilanswer
 

sielfried a écrit :

Ouais mais il a dit que les IDs étaient pas forcément dans l'ordre je crois.


La requête que j'ai donnée plus haut elle a pas besoin que les IDs se suivent hein :o

sielfried a écrit :

Du coup j'ai supposé que ces "dates" étaient des datetime (auquel cas je pense que mon truc fonctionne).


Pas vraiment, tu peux très bien avoir plusieurs enregistrement avec exactement le même timestamp dans une table. Ca arrive même régulièrement quand tu as des  "insert into taTable ( ..., champs_date) select ... current_timestamp .

sielfried a écrit :

edit: j'ai rien dit mon truc marchera jamais, d'ailleurs celles d'au dessus non plus (faut forcément un join ou un union quelque part)


ça c'est sur [:dawak]

darxmurf a écrit :

en passant, j'ai essayé de faire une bête requête
SELECT MAX(date), name FROM table ... LIMIT 1
et il me retourne qu'il faut mettre un GROUP BY [:paysan] pourquoi ?


L'utilisation d'un aggregat (max, min, sum, count, ...) impose l'utilisation du group by sur les colonnes "non-aggrégées". MySQL fait preuve de souplesse la-dessus, mais uniquement jusqu'à un certain point.

 
casimimir a écrit :

on peut mettre un min ou un max dans un case en mysql(quasi jamais utilisé)?
en oracle a la limite on pourrait en utilisant les min/max version fonction analytique, mais la il ralerait direct.


on peut faire n'importe quoi avec MySQL ;)
mais moi ce qui me surprend le plus c'est qu'il accepte le T2.* dans le select sans qu'il soit dans le group by.

Message cité 1 fois
Message édité par anapajari le 29-04-2008 à 16:56:48

---------------
Software and cathedrals are much the same - first we build them, then we pray.
n°1726398
darxmurf
meow
Posté le 29-04-2008 à 16:55:27  profilanswer
 

Bon au final pour pas me faire chier et pour faire des manip supplémentaires, j'ai fais 3 requêtes séparées ... [:tinostar]
 
Merci quand même j'ai 2 ou 3 trucs qui me serviront par la suite dans tous vos posts :jap:


---------------
Des trucs - flickr - Instagram
n°1726412
sielfried
Posté le 29-04-2008 à 17:12:28  profilanswer
 

anapajari a écrit :


La requête que j'ai donnée plus haut elle a pas besoin que les IDs se suivent hein :o


 
Pas dans l'ordre != se suivent pas.
 
Genre t'ajoute une photo en lui foutant la date d'il y a trois semaines, je sais pas. [:dawa]
 
C'est assez débile pour une date, mais rien ne l'empêche techniquement (on a plutôt ce genre de cas avec des listes dans lesquelles on peut aller insérer un truc en plein milieu, auquel cas on peut pas se baser sur l'ID).


---------------
StarCraft Professional Gaming Database | [Ze Topic] Starcraft/BroodWar
n°1726417
anapajari
s/travail/glanding on hfr/gs;
Posté le 29-04-2008 à 17:16:06  profilanswer
 

pas tort :o
Mais dans ce cas là, au lieu de faire sign(T1.id - T2.id) suffit de faire sign(T1.date - T2.date) et ça marche pareil ...


---------------
Software and cathedrals are much the same - first we build them, then we pray.
mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  [MySQL] SELECT une entrée, celle d'avant et celle d'après en 1 fois ?

 

Sujets relatifs
Problème erreur ifproblème de lecture/écriture sur entrée/sortie en Java
afficher des image stocker dans bdd mysql[MYSQL] supprimer 'doublon' lors d'un select
[Résolu 2 fois ;)] script PHP liste deroulante et base de donnéesSimuler un "ctrl+tab" + "entrée"
[MySQL] SELECT COUNT + grouper par plages de valeursMYsql je n'y comprend rien, et formulaire non plus
Plus de sujets relatifs à : [MySQL] SELECT une entrée, celle d'avant et celle d'après en 1 fois ?


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR