Jednym ze sposobów jest użycie widoku wbudowanego, takiego jak zapytanie, które już masz. Ale zamiast używać DISTINCT, użyjesz GROUP BY, aby wyeliminować duplikaty. Najprostszy widok wbudowany spełniający Twoje wymagania to:
( SELECT n.item_number, n.name, n.type_code
FROM itpitnam n
GROUP BY n.item_number
) itpitnam
Chociaż nie jest to deterministyczne, z którego wiersza z itpitnam są pobierane wartości name i type_code. Bardziej rozbudowany widok wbudowany może sprawić, że będzie to bardziej szczegółowe.
Innym powszechnym podejściem do tego typu problemu jest użycie skorelowanego podzapytania na liście SELECT. W przypadku zwracania małego zestawu wierszy może to działać dość dobrze. Ale w przypadku zwracania dużych zestawów istnieją bardziej wydajne podejścia.
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
To zapytanie zwróci określony zestaw wyników z jedną istotną różnicą. Oryginalne zapytanie pokazuje INNER JOIN do itpitnam
stół. Oznacza to, że wiersz zostanie zwrócony TYLKO z pasującego wiersza w itpitnam
stół. Powyższe zapytanie emuluje jednak OUTER JOIN, zapytanie zwróci wiersz, gdy nie zostanie znaleziony pasujący wiersz w itpitnam
.
AKTUALIZACJA
Aby uzyskać najlepszą wydajność tych skorelowanych podzapytań, potrzebny będzie odpowiedni indeks,
... ON itpitnam (item_number, type_code, name)
Ten indeks jest najbardziej odpowiedni, ponieważ jest to „indeks pokrywający”, zapytanie może być wykonane w całości z indeksu bez odwoływania się do stron danych w tabeli bazowej, a w kolumnie wiodącej występuje predykat równości, a w kolejnych dwóch kolumnach ORDER BY. dzięki czemu unikniemy operacji sortowania.
--
Jeśli masz gwarancję, że type_code
lub name
kolumna w tabeli itpitnam NIE JEST NULL, możesz dodać predykat, aby wyeliminować wiersze, w których „brakuje” pasującego wiersza, np.
HAVING artist IS NOT NULL
(Dodanie tego prawdopodobnie będzie miało wpływ na wydajność.) W przypadku braku tego rodzaju gwarancji należałoby dodać INNER JOIN lub predykat sprawdzający istnienie pasującego wiersza, aby uzyskać zachowanie INNER JOIN.