Requête SQL tri colonne

Eléphanteau du PHP | 47 Messages

30 janv. 2010, 16:04

Bonjour,

Le code suivant permet par un clic sur le nom de la colonne "AUTEUR" ou "TITRE" de me retourner la totalité des livres de ma base triés sur le champ adéquat :
<?php

// Connexion à la base de donnée
require_once("connexionMysql.inc.php");

// Le nom de notre table
$tablename = 'liste';

$ID_AUTEUR = (iSset($_GET['ID_AUTEUR']) ? $_GET['ID_AUTEUR'] : null);
$GENRE = (iSset($_GET['GENRE']) ? $_GET['GENRE'] : null);

// Tri sur colonne
$tri_autorises = array('TITRE','AUTEUR');

if(!isset($_GET['order'])) $_GET['order']="";
$order_by = in_array($_GET['order'],$tri_autorises) ? $_GET['order'] : 'TITRE';

// Sens du tri
$order_dir = isset($_GET['inverse']) ? 'DESC' : 'ASC';

// Préparation de la requête

$requete = "
	SELECT *
	FROM {$tablename}
	ORDER BY {$order_by} {$order_dir}
";

if ( $ID_AUTEUR != null) { // on ajoute le critère que s'il est demandé
  $requete  .= " WHERE ID_AUTEUR=".$ID_AUTEUR; // 
}
if ( $GENRE != null) { // on ajoute le critère que s'il est demandé
  $requete  .= " WHERE GENRE='".$GENRE."'"; //
}

$resultat = mysql_query($requete) or die('Erreur SQL !'.$requete.'<br>'.mysql_error());


// fonction qui affiche les liens
function sort_link($text, $order=false)
{
	global $order_by, $order_dir;

	if(!$order)
		$order = $text;

	$link = '<a href="?order=' . $order;
	if($order_by==$order && $order_dir=='ASC')
		$link .= '&inverse=true';
	$link .= '"';
	if($order_by==$order && $order_dir=='ASC')
		$link .= ' class="order_asc"';
	elseif($order_by==$order && $order_dir=='DESC')
		$link .= ' class="order_desc"';
	$link .= '>' . $text . '</a>';

	return $link;
}


// Affichage
?>
<style type="text/css">
a.order_asc,
a.order_desc:hover { 
	padding-right:15px;
	background:transparent url(s_asc.png) right no-repeat;
}
a.order_desc,
a.order_asc:hover {
	padding-right:15px;
	background:transparent url(s_desc.png) right no-repeat;
}
</style>

<table>
	<tr>
		<th><?php echo sort_link('Auteur', 'AUTEUR') ?></th>
		<th><?php echo sort_link('Titre', 'TITRE') ?>

		
	</tr>
<?php while( $row=mysql_fetch_assoc($resultat) ) : ?>
	<tr>
	
		<td><a href="tri_alternatif.php?ID_AUTEUR=<?php echo $row['ID_AUTEUR']; ?>"><?php echo $row['AUTEUR']; ?></a><td>
		<td><?php echo $row['TITRE'] ?></td>
	</tr>
<?php endwhile ?>
</table>
En cliquant sur le lien :
<a href="tri_alternatif.php?ID_AUTEUR=<?php echo $row['ID_AUTEUR']; ?>"><?php echo $row['AUTEUR']; ?></a>
je souhaiterais trier uniquement les livres d'un seul auteur identifié par son ID_AUTEUR. Mais j'ai l'erreur suivante : "Erreur SQL ! SELECT * FROM liste ORDER BY TITRE ASC WHERE ID_AUTEUR=22 You have an error in your SQL syntax". Voyez-vous comment régler cette erreur ? Merci.

Mammouth du PHP | 2937 Messages

30 janv. 2010, 16:12

Essaie d'inverser l'ordre d'apparition des clauses ORDER BY et WHERE, comme suit :
$requete = "SELECT *
        FROM ".$tablename;

if ( $ID_AUTEUR != null) { // on ajoute le critère que s'il est demandé
  $requete  .= " WHERE ID_AUTEUR = ".$ID_AUTEUR; // 
}
if ( $GENRE != null) { // on ajoute le critère que s'il est demandé
  $requete  .= " WHERE GENRE = '".$GENRE."'"; //
}
$requete .= " ORDER BY ".$order_by." ".$order_dir;
Ce qui donne, par exemple, la requête SQL suivante :
SELECT * FROM liste WHERE ID_AUTEUR = 22 ORDER BY TITRE ASC

ViPHP
ViPHP | 2291 Messages

30 janv. 2010, 16:52

ImageCe que l'on apprend par l'effort reste toujours ancré beaucoup plus longtemps.

Eléphanteau du PHP | 47 Messages

30 janv. 2010, 17:17

A Dunbar : l'objet du code est le même mais celui-ci introduit une variante avec une fonction permettant de gérer le tri ascendant et descendant de façon plus optimisée :P
Pour répondre à Victor BRITO : l'inversion résout l'erreur et me permet d'afficher la liste des livres d'un auteur en fonction de son ID. Mais je n'arrive pas à faire fonctionner le tri de façon correcte sur cette liste de l'auteur : le tri s'effectue sur l'ensemble de mes livres et non pas que sur les livres de l'auteur.
Je comprends qu'il faut récupérer la variable ID_AUTEUR pour qu'elle s'ajoute à l'URL de type :
...tri_alternatif.php?order=TITRE&inverse=true&ID_AUTEUR=
mais je n'y arrive pas. Je pense que c'est au niveau de la fonction qu'il faut ajouter la variable ID_AUTEUR :
function sort_link($text, $order=false)
{
	global $order_by, $order_dir;

	if(!$order)
		$order = $text;

	$link = '<a href="?order=' . $order ; // Comment faire pour ajouter la variable ID_AUTEUR pour arriver à l'effet escompté ?
	if($order_by==$order && $order_dir=='ASC')
		$link .= '&inverse=true';
	$link .= '"';
	if($order_by==$order && $order_dir=='ASC')
		$link .= ' class="order_asc"';
	elseif($order_by==$order && $order_dir=='DESC')
		$link .= ' class="order_desc"';
	$link .= '>' . $text . '</a>';

	return $link;
}
Pouvez-vous m'aider ? Merci.

Eléphant du PHP | 168 Messages

01 févr. 2010, 12:03

Est-ce que tu as essayé la requête obtenue dans phpmyadmin?

Eléphanteau du PHP | 47 Messages

01 févr. 2010, 19:03

Avec de l'aide, j'ai finalement réussi à modifier la fonction pour arriver à l'effet escompté. Pour information celle-ci est la suivante :
function sort_link($text,$order=false)
{
	global $order_by, $order_dir;
 
	if(!$order)
		$order = $text;
	

	$link = '<a href="?order=' . $order ;
	
	if (isset($_GET['ID_AUTEUR'])) {            
     $link .= "&ID_AUTEUR=".$_GET['ID_AUTEUR'];	 
	}
	
	if (isset($_GET['GENRE'])) {            
     $link .= "&GENRE=".$_GET['GENRE'];	
	}
	
	
	if($order_by==$order && $order_dir=='ASC')
		$link .= '&inverse=true';
	$link .= '"';
	if($order_by==$order && $order_dir=='ASC')
		$link .= ' class="order_asc"';
	elseif($order_by==$order && $order_dir=='DESC')
	$link .= ' class="order_desc"';
	
	$link .= '>' . $text . '</a>';
 
	return $link;
}