Clause Where

Mammouth du PHP | 531 Messages

31 janv. 2008, 13:19

Bonjour,

Voilà j'épluche la doc http://dev.mysql.com/doc/refman/5.0/fr/functions.html depuis quelques temps ce matin et je ne trouve pas comment faire cela en une seule requête :

SELECT contenu FROM table WHERE [ la valeur du champ position est la plus petite de toute la colonne]

En fait je ne sais même pas si c'est possible ?
Sinon en deux requêtes c'est facilement possible mais le but est aussi de réduire le nombre de requêtes...

:?

Code : Tout sélectionner

CREATE TABLE IF NOT EXISTS thinkcms_mod_pages ( id int(11) NOT NULL auto_increment, nom varchar(25) character set utf8 collate utf8_bin NOT NULL, contenu text collate utf8_unicode_ci NOT NULL, position int(3) NOT NULL, visible int(1) NOT NULL, PRIMARY KEY (id) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1";

lux
Eléphant du PHP | 372 Messages

31 janv. 2008, 13:45

Avec un

Code : Tout sélectionner

SELECT MIN(id),contenu FROM ...
non ?

Mammouth du PHP | 531 Messages

31 janv. 2008, 13:54

Avec un

Code : Tout sélectionner

SELECT MIN(id),contenu FROM ...
non ?
Si je fait ça je vais sélectionner l'id minimum de la colone.
Ce que je veut c'est sélectionner le contenu de la ligne ou sa position est la plus petite de toute la colone position.

Je sais pas si je m'explique bien... :?
Mais je pense sans en être sur que tout va se passer dans WHERE ?

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

31 janv. 2008, 13:55

Peut être avec un

Code : Tout sélectionner

SELECT contenu FROM table WHERE position = MIN(position)
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Mammouth du PHP | 531 Messages

31 janv. 2008, 13:57

Peut être avec un

Code : Tout sélectionner

SELECT contenu FROM table WHERE position = MIN(position)
J'ai déjà essayé...
]$req_page = "SELECT contenu FROM thinkcms_mod_pages WHERE position = MIN(position)"; // Requete page
			$result_page = mysql_query($req_page);
			$data_page = mysql_fetch_array($result_page);
			echo $data_page['contenu'];
Affiche :

Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in /home/users2/s/supercanard/www/thinkcms/test/modules/mod_pages/index.php on line 28

(L 28 : $data_page = mysql_fetch_array($result_page);)

ViPHP
ViPHP | 5924 Messages

31 janv. 2008, 14:00


Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

31 janv. 2008, 14:01

La 1ère règle quand tu construis une requête, c'est de ne pas additionner les sources d'erreur.

Prend ta requête, exécutes là dans un phpMyAdmin et viens nous donner le message d'erreur MySQL, pas PHP
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Mammouth du PHP | 531 Messages

31 janv. 2008, 14:03

Oups oublié le mysql_error() ...

mysql_error : Invalid use of group function

ViPHP
ViPHP | 5924 Messages

31 janv. 2008, 14:07

Tu peux peut être essayer de remplacer le WHERE par un HAVING :-/

Mammouth du PHP | 531 Messages

31 janv. 2008, 14:23

Tu peux peut être essayer de remplacer le WHERE par un HAVING :-/
Ah cool, ça à l'air génialement puissant HAVING :D
Je connaissais que WHERE. Bon je suis pas sur d'avoir totalement compris la différence, je suis en train de lire une doc mais c'est expliqué en terme très technique, pour l'instant j'ai du mal... je m'y remet après la pause dej !

Sinon petit essai vite fait : HAVING position = MIN(position) -> Unknown column 'position' in 'having clause'

Mais bon comme j'ai pas encore comprit la subtilité de HAVING j'ai collé ça comme ça donc sans commentaires :wink:

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

31 janv. 2008, 15:14

en deux requêtes c'est facilement possible mais le but est aussi de réduire le nombre de requêtes...
Pour des requêtes aussi simples, la différence de performance entre la version à 1 requête et la version à 2 requêtes est négligible. À moins d'effectuer cette opération 10 fois par page, tu ne pourrais même pas le chronométrer.

Ceci dit, voici comment tu peux le faire en une seule requête (MySQL 4.1+)

Code : Tout sélectionner

SELECT contenu FROM table WHERE position = ( SELECT MIN(position) FROM table )
Attention, cette requête peut renvoyer plusieurs enregistrements, pour peu qu'ils partagent la même valeur pour "position". Ajoute un "LIMIT 1" pour n'en récupérer qu'un seul.

Une requête similaire pour les anciennes versions de MySQL, potentiellement plus rapide.

Code : Tout sélectionner

SELECT contenu FROM table ORDER BY position LIMIT 1
Dernière chose, si tu t'inquiètes pour tes performances, tu ferais mieux de t'intéresser aux index plutôt, et ajouter un index sur la colonne "position".
HAVING position = MIN(position) -> Unknown column 'position' in 'having clause'
C'est parce que HAVING est l'équivalent d'un WHERE qui agit sur le résultat de ta requête. "position" n'apparaît pas dans ton SELECT, donc c'est comme un WHERE sur une colonne qui n'existe pas.

Mammouth du PHP | 531 Messages

31 janv. 2008, 16:25

Merci pour les explications :wink:

Je savais pas nom plus que l'on pouvais faire ça et ça change pas mal de choses :

Code : Tout sélectionner

SELECT contenu FROM table WHERE position = ( SELECT MIN(position) FROM table )
Ce type de requête à un nom spécifique ?

ViPHP
ViPHP | 4039 Messages

31 janv. 2008, 17:13

simplement une sous-requête. tu peux en faire partout, et plein mille :wink:
Mais qu'importe. (je suis ici - dernier petit projet)
Berze going social.