Ein Ansatz besteht darin, eine Inline-Ansicht zu verwenden, wie die Abfrage, die Sie bereits haben. Aber anstatt DISTINCT zu verwenden, würden Sie ein GROUP BY verwenden, um Duplikate zu eliminieren. Die einfachste Inline-Ansicht zur Erfüllung Ihrer Anforderungen wäre:
( SELECT n.item_number, n.name, n.type_code
FROM itpitnam n
GROUP BY n.item_number
) itpitnam
Obwohl es nicht deterministisch ist, aus welcher Zeile von itpitnam die Werte für name und type_code abgerufen werden. Eine ausgefeiltere Inline-Ansicht kann dies spezifischer machen.
Ein weiterer gängiger Ansatz für diese Art von Problem ist die Verwendung einer korrelierten Unterabfrage in der SELECT-Liste. Für die Rückgabe eines kleinen Satzes von Zeilen kann dies recht gut funktionieren. Aber für die Rückgabe großer Sätze gibt es effizientere Ansätze.
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
Diese Abfrage gibt das angegebene Resultset mit einem signifikanten Unterschied zurück. Die ursprüngliche Abfrage zeigt einen INNER JOIN zu itpitnam
Tisch. Das bedeutet, dass NUR eine Zeile zurückgegeben wird, wenn es eine passende Zeile in itpitnam
gibt Tisch. Die obige Abfrage emuliert jedoch einen OUTER JOIN, die Abfrage gibt eine Zeile zurück, wenn keine übereinstimmende Zeile in itpitnam
gefunden wird .
AKTUALISIEREN
Für die beste Leistung dieser korrelierten Unterabfragen benötigen Sie einen geeigneten verfügbaren Index,
... ON itpitnam (item_number, type_code, name)
Dieser Index ist am besten geeignet, da es sich um einen "abdeckenden Index" handelt, die Abfrage vollständig aus dem Index ausgeführt werden kann, ohne auf Datenseiten in der zugrunde liegenden Tabelle zu verweisen, und es ein Gleichheitsprädikat für die führende Spalte und ein ORDER BY für die nächsten beiden Spalten gibt. damit wird eine "Sortieren"-Operation vermieden.
--
Wenn Sie eine Garantie haben, dass entweder der type_code
oder name
Spalte in der itpitnam-Tabelle NICHT NULL ist, können Sie ein Prädikat hinzufügen, um die Zeilen zu eliminieren, denen eine passende Zeile "fehlt", z. B.
HAVING artist IS NOT NULL
(Das Hinzufügen wird sich wahrscheinlich auf die Leistung auswirken.) Ohne diese Art von Garantie müssten Sie einen INNER JOIN oder ein Prädikat hinzufügen, das auf das Vorhandensein einer übereinstimmenden Zeile testet, um ein INNER JOIN-Verhalten zu erhalten.