Une approche consiste à utiliser une vue en ligne, comme la requête que vous avez déjà. Mais au lieu d'utiliser DISTINCT, vous utiliseriez un GROUP BY pour éliminer les doublons. La vue en ligne la plus simple pour répondre à vos besoins serait :
( SELECT n.item_number, n.name, n.type_code
FROM itpitnam n
GROUP BY n.item_number
) itpitnam
Bien qu'il ne soit pas déterministe quant à la ligne d'itpitnam à partir de laquelle les valeurs de name et type_code sont récupérées. Une vue en ligne plus élaborée peut rendre cela plus spécifique.
Une autre approche courante de ce type de problème consiste à utiliser une sous-requête corrélée dans la liste SELECT. Pour renvoyer un petit ensemble de lignes, cela peut fonctionner raisonnablement bien. Mais pour renvoyer de grands ensembles, il existe des approches plus efficaces.
SELECT i.identifier
, i.name
, i.subtitle
, i.description
, i.itemimg
, i.mainprice
, i.upc
, i.isbn
, i.weight
, i.pages
, i.publisher
, i.medium_abbr
, i.medium_desc
, i.series_abbr
, i.series_desc
, i.voicing_desc
, i.pianolevel_desc
, i.bandgrade_desc
, i.category_code
, r.overall_ranking
, ( SELECT n1.name
FROM itpitnam n1
WHERE n1.item_number = r.item_number
ORDER BY n1.type_code, n1.name
LIMIT 1
) AS artist
, ( SELECT n2.type_code
FROM itpitnam n2
WHERE n2.item_number = r.item_number
ORDER BY n2.type_code, n2.name
LIMIT 1
) AS type_code
FROM itpitems i
JOIN itprank r
ON r.item_number = i.identifier
WHERE mainprice > 1
LIMIT 3
Cette requête renverra le jeu de résultats spécifié, avec une différence significative. La requête d'origine montre un INNER JOIN au itpitnam
table. Cela signifie qu'une ligne sera renvoyée UNIQUEMENT s'il existe une ligne correspondante dans le itpitnam
table. La requête ci-dessus, cependant, émule une OUTER JOIN, la requête renverra une ligne lorsqu'il n'y a pas de ligne correspondante trouvée dans itpitnam
.
MISE À JOUR
Pour de meilleures performances de ces sous-requêtes corrélées, vous aurez besoin d'un index approprié disponible,
... ON itpitnam (item_number, type_code, name)
Cet index est le plus approprié car il s'agit d'un "index de couverture", la requête peut être entièrement satisfaite à partir de l'index sans référencer les pages de données dans la table sous-jacente, et il y a un prédicat d'égalité sur la colonne principale et un ORDER BY sur les deux prochaines colonnes, cela évitera une opération de "tri".
--
Si vous avez la garantie que soit le type_code
ou name
colonne dans la table itpitnam est NOT NULL, vous pouvez ajouter un prédicat pour éliminer les lignes qui "manquent" une ligne correspondante, par exemple
HAVING artist IS NOT NULL
(L'ajout de cela aura probablement un impact sur les performances.) En l'absence de ce type de garantie, vous devez ajouter un INNER JOIN ou un prédicat qui teste l'existence d'une ligne correspondante, pour obtenir un comportement INNER JOIN.