sql >> Database teknologi >  >> RDS >> Mysql

Brug af DISTINCT inde i JOIN skaber problemer

En tilgang er at bruge en inline-visning, ligesom den forespørgsel, du allerede har. Men i stedet for at bruge DISTINCT, ville du bruge en GROUP BY til at eliminere dubletter. Den enkleste indlejrede visning til at opfylde dine krav ville være:

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

Selvom det ikke er deterministisk med hensyn til, hvilken række fra itpitnam værdierne for navn og type_code hentes fra. En mere detaljeret indlejret visning kan gøre dette mere specifikt.

En anden almindelig tilgang til denne type problemer er at bruge en korreleret underforespørgsel i SELECT-listen. For at returnere et lille sæt rækker kan dette fungere rimeligt godt. Men for at returnere store sæt er der mere effektive tilgange.

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

Denne forespørgsel vil returnere det angivne resultatsæt med én væsentlig forskel. Den oprindelige forespørgsel viser en INNER JOIN til itpitnam bord. Det betyder, at en række KUN returneres, hvis der er en matchende række i itpitnam bord. Forespørgslen ovenfor emulerer dog en OUTER JOIN, forespørgslen returnerer en række, når der ikke findes en matchende række i itpitnam .

OPDATERING

For at opnå den bedste ydeevne af disse korrelerede underforespørgsler skal du have et passende indeks tilgængeligt,

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

Det indeks er mest passende, fordi det er et "dækkende indeks", forespørgslen kan opfyldes helt fra indekset uden at referere til datasider i den underliggende tabel, og der er lighedsprædikat på den forreste kolonne og en ORDER BY i de næste to kolonner, så det vil undgå en "sorterings"-operation.

--

Hvis du har en garanti for, at enten type_code eller name kolonnen i itpitnam-tabellen IKKE er NULL, kan du tilføje et prædikat for at eliminere de rækker, der "mangler" en matchende række, f.eks.

HAVING artist IS NOT NULL

(Hvis du tilføjer det, vil det sandsynligvis have en indvirkning på ydeevnen.) Uden den slags garanti skal du tilføje en INNER JOIN eller et prædikat, der tester for eksistensen af ​​en matchende række, for at få en INNER JOIN-adfærd.



  1. Mysql problem ved oprettelse af en ny bruger

  2. Kald en lagret procedure fra DECLARE-sætningen, når du bruger markører i MySQL

  3. Bedste praksis for bulk_create til massive registreringer

  4. Hvordan dumper man kun specifikke tabeller fra MySQL?