sql >> Databasteknik >  >> RDS >> Mysql

Att använda DISTINCT i JOIN skapar problem

Ett tillvägagångssätt är att använda en inline-vy, som den fråga du redan har. Men istället för att använda DISTINCT, skulle du använda en GROUP BY för att eliminera dubbletter. Den enklaste inlinevyn för att tillfredsställa dina krav skulle vara:

( SELECT n.item_number, n.name, n.type_code
    FROM itpitnam n
   GROUP BY n.item_number
) itpitnam

Även om det inte är deterministiskt för vilken rad från itpitnam värdena för namn och typ_kod hämtas från. En mer utarbetad inline-vy kan göra detta mer specifikt.

Ett annat vanligt tillvägagångssätt för denna typ av problem är att använda en korrelerad underfråga i SELECT-listan. För att returnera en liten uppsättning rader kan detta fungera ganska bra. Men för att returnera stora uppsättningar finns det mer effektiva metoder.

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

Den frågan kommer att returnera den angivna resultatuppsättningen, med en signifikant skillnad. Den ursprungliga frågan visar en INNER JOIN till itpitnam tabell. Det betyder att en rad ENDAST kommer att returneras om det finns en matchande rad i itpitnam tabell. Frågan ovan emulerar dock en OUTER JOIN, frågan returnerar en rad när det inte finns någon matchande rad i itpitnam .

UPPDATERA

För bästa prestanda för dessa korrelerade underfrågor vill du ha ett lämpligt index tillgängligt,

... ON itpitnam (item_number, type_code, name)

Det indexet är mest lämpligt eftersom det är ett "täckande index", frågan kan tillfredsställas helt från indexet utan att referera till datasidor i den underliggande tabellen, och det finns likhetspredikat på den inledande kolumnen och en ORDER BY i de nästa två kolumnerna, så att man undviker en "sorteringsoperation".

--

Om du har en garanti för att antingen type_code eller name kolumnen i itpitnam-tabellen INTE är NULL, du kan lägga till ett predikat för att eliminera raderna som "saknar" en matchande rad, t.ex.

HAVING artist IS NOT NULL

(Att lägga till det kommer sannolikt att påverka prestandan.) I avsaknad av den typen av garanti skulle du behöva lägga till en INNER JOIN eller ett predikat som testar om det finns en matchande rad, för att få ett INNER JOIN-beteende.



  1. välj liknande värden från mysql-databasen

  2. MySQL INFOGA annat om det finns UPPDATERING

  3. Lägg till ett databaspostkonto till en profil (SSMS)

  4. JSP-kodning medan icke-engelsk text infogas i MySQL-databasen