#-- Trouver les articles de plus de 50 euros.
SELECT * from articles WHERE prix >50.0;

#-- Lister les noms des articles, triés par prix.
# Les trier par catégorie, puis par stock pour une même catégorie.
SELECT nom, prix FROM articles ORDER BY prix DESC;
SELECT nom, prix, idcategorie FROM articles ORDER BY idcategorie ASC, prix DESC;

#-- Afficher toutes les commandes de 2004, puis les 3 commandes les plus récentes.
SELECT * FROM commandes WHERE date LIKE '2004%';
# OU   
SELECT * FROM commandes WHERE date BETWEEN '2004-00-00' AND '2005-00-00';
SELECT * FROM commandes ORDER BY date DESC LIMIT 3;

#-- Quelles différences entre les deux lignes : 
# SELECT COUNT(*) FROM articles ;
# SELECT COUNT(articles.codearticle) FROM articles ;

#-- Combien d'articles de squash a-t-on ?
SELECT COUNT(*) FROM articles WHERE nom LIKE '%squash%' ;



# Afficher tous les articles classés dans la même catégorie que le tuba
SELECT a1.codearticle, a1.nom, a1.prix 
  FROM articles a1 
  JOIN articles a2 USING (idcategorie) 
 WHERE a2.nom = "tuba" ;

# Afficher tous les articles moins chers que le tuba
# jointure
SELECT a1.codearticle, a1.nom, a1.prix 
  FROM articles a1 
  JOIN articles a2 ON (a1.prix < a2.prix) 
  WHERE a2.nom = "tuba" ;

# Variante sous-requête 
SELECT a1.codearticle, a1.nom, a1.prix 
  FROM articles a1  
 WHERE a1.prix < (SELECT prix FROM articles a2 WHERE nom="tuba" );


# Trouver tous les prix qui ont changé entre la commande (detail.prix)
# et le catalogue (article.prix)

# Méthode 1 : jointure
SELECT a.codearticle, a.prix AS PrixA, d.prix AS PrixD 
  FROM articles a 
  JOIN details d USING (codearticle) 
WHERE a.prix != d.prix ;

# Méthode 2 : UNION + sous-requête 
SELECT codearticle , COUNT(distinct prix) Cpt FROM 
    ( SELECT codearticle, prix FROM articles A 
      UNION ALL 
      SELECT DISTINCT codearticle, prix from details D
    ) U GROUP BY codearticle HAVING Cpt>1;

# Méthode 3 (mauvaise) : focus uniquement sur les prix
SELECT prix FROM details WHERE prix NOT IN (SELECT prix FROM articles) ;



# Trouver l''article le plus cher (code, nom, prix)
# Par le plus grand nombre de méthodes différentes !

# Méthode 0 : inconvénient ?
SELECT nom, codearticle, prix 
  FROM articles 
ORDER BY prix DESC LIMIT 1;

# Méthode 1 : sous-requête
SELECT nom, codearticle, prix 
  FROM articles 
 WHERE prix = (SELECT MAX(prix) FROM articles);

# Méthode 2 : variable intermédiaire
SET @maxi=(SELECT MAX(prix) FROM articles) ;
SELECT nom, codearticle, prix FROM articles WHERE prix=@maxi ;

# Méthode 3 : auto-jointure
SELECT a1.codearticle, a1.nom, a1.prix  
  FROM articles a1 
LEFT JOIN articles a2 ON (a1.prix < a2.prix) 
WHERE a2.codearticle IS NULL ;

# Méthode 4 : sous-requête sans agrégation
SELECT nom, codearticle, prix 
  FROM articles 
WHERE prix >= ALL(SELECT prix FROM articles) ;



# 1. Trouver tous les prix multiples (prix identiques pour plusieurs articles)
# 2. Afficher tous les articles concernés
# Q1 :
SELECT prix, COUNT(*) AS nb 
  FROM articles 
  GROUP BY prix HAVING nb>1 ;

# 2.a  méthode 1 : auto-jointure
SELECT DISTINCT a1.codearticle, a1.nom, a1.prix 
  FROM articles a1 
  JOIN articles a2 USING (prix)
WHERE a1.codearticle != a2.codearticle ;

# 2.b méthode 2 : sous-requêtes
SELECT codearticle, nom, prix FROM articles 
WHERE prix IN (
    SELECT prix FROM articles 
    GROUP BY prix HAVING COUNT(codearticle)>1
    );

# 2.c méthode 3 : presque de la triche !
SELECT prix, COUNT(*) AS nb, GROUP_CONCAT(codearticle) AS articles_id
  FROM articles 
  GROUP BY prix HAVING nb>1 ;



# Assigner un rang aux articles, classés par prix décroissant
# (numéro 1 = le plus cher).
# La requête affiche une table articles "augmentée" sans modifier l''originale

# 1. rang "naïf" : on ne tient pas compte des égalités
SET @ligne := 0;
SELECT @ligne := @ligne+1 AS Rang, prix, codearticle, nom
  FROM articles ORDER BY prix DESC ;

# 2. rang "statistique" : on tient compte des égalités, on ne saute pas de rang
SET @rang := 0, @prec := NULL;
SELECT @rang := IF(prix=@prec,@rang,@rang+1) AS Rang, @prec:=prix AS prix, codearticle, nom
  FROM articles ORDER BY prix DESC ;

# 3. rang "sportif" : on tient compte des égalités, on saute les rangs attribués aux ex-aequo
SET @ligne:=0, @rang:=0, @prec:=NULL;
SELECT @ligne:= @ligne+1 AS Ligne, @rang := IF(prix=@prec,@rang,@ligne) AS Rang, @prec:=prix AS prix, codearticle, nom
  FROM articles ORDER BY prix DESC ;

