Един подход е да използвате вграден изглед, като заявката, която вече имате. Но вместо да използвате DISTINCT, ще използвате GROUP BY за премахване на дубликати. Най-простият вграден изглед, който да удовлетвори вашите изисквания, би бил:
( SELECT n.item_number, n.name, n.type_code
FROM itpitnam n
GROUP BY n.item_number
) itpitnam
Въпреки че не е детерминистично от кой ред от itpitnam се извличат стойностите за name и type_code. По-сложен вграден изглед може да направи това по-конкретно.
Друг често срещан подход към този тип проблеми е използването на корелирана подзаявка в списъка SELECT. За връщане на малък набор от редове това може да се представи сравнително добре. Но за връщането на големи набори има по-ефективни подходи.
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
Тази заявка ще върне посочения набор от резултати, с една значителна разлика. Оригиналната заявка показва INNER JOIN към itpitnam
маса. Това означава, че ред ще бъде върнат САМО ако има съвпадащ ред в itpitnam
маса. Заявката по-горе обаче емулира OUTER JOIN, заявката ще върне ред, когато няма съвпадащ ред, намерен в itpitnam
.
АКТУАЛИЗИРАНЕ
За най-добра производителност на тези корелирани подзаявки ще искате наличен подходящ индекс,
... ON itpitnam (item_number, type_code, name)
Този индекс е най-подходящ, защото е "покриващ индекс", заявката може да бъде удовлетворена изцяло от индекса, без да се препраща към страници с данни в основната таблица, и има предикат за равенство в водещата колона и ORDER BY в следващите две колони, така че това ще избегне операция "сортиране".
--
Ако имате гаранция, че или type_code
или name
колоната в таблицата itpitnam НЕ е NULL, можете да добавите предикат, за да елиминирате редовете, на които „липсва“ съвпадащ ред, напр.
HAVING artist IS NOT NULL
(Добавянето на това вероятно ще окаже влияние върху производителността.) При липса на такъв вид гаранция, ще трябва да добавите INNER JOIN или предикат, който тества за съществуването на съвпадащ ред, за да получите поведение INNER JOIN.