1つのアプローチは、すでに持っているクエリのように、インラインビューを使用することです。ただし、DISTINCTを使用する代わりに、GROUPBYを使用して重複を排除します。要件を満たすための最も単純なインラインビューは次のとおりです。
( 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
そのクエリは、1つの重要な違いを除いて、指定された結果セットを返します。元のクエリは、itpitnam
への内部結合を示しています テーブル。つまり、itpitnam
に一致する行がある場合にのみ行が返されます。 テーブル。ただし、上記のクエリはOUTER JOINをエミュレートし、itpitnam
に一致する行が見つからない場合、クエリは行を返します。 。
更新
これらの相関サブクエリのパフォーマンスを最高にするには、適切なインデックスを利用できるようにする必要があります。
... ON itpitnam (item_number, type_code, name)
このインデックスは「カバーインデックス」であり、基になるテーブルのデータページを参照せずにインデックスからクエリを完全に満たすことができ、先頭の列に等式述語があり、次の2つの列にORDER BYがあるため、このインデックスが最も適切です。これにより、「ソート」操作が回避されます。
-
type_code
のいずれかが保証されている場合 またはname
itpitnamテーブルの列がNULLでない場合、述語を追加して、一致する行が「欠落している」行を削除できます。例:
HAVING artist IS NOT NULL
(これを追加すると、パフォーマンスに影響を与える可能性があります。)この種の保証がない場合、INNER JOINの動作を取得するには、INNERJOINまたは一致する行の存在をテストする述語を追加する必要があります。
>