Mysql
 sql >> база данни >  >> RDS >> Mysql

Използването на DISTINCT в JOIN създава проблеми

Един подход е да използвате вграден изглед, като заявката, която вече имате. Но вместо да използвате 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.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Използване на променлива env в application.properties на Spring Boot

  2. MYSQL last_insert_id() и едновременност

  3. Qt QMYSQL драйверът не е зареден в Windows

  4. apache mysql - пакети извън ред на 3306

  5. SQL инжекции в ADOdb и обща сигурност на уебсайта