2つのテーブルがあります。1つ(ARTISTS
)には、さまざまなアーティスト、詳細、伝記のリストが含まれていますが、画像は含まれていません。必要な画像を含む、オークション結果が満載の別のテーブル(ARCHIVECATALOGUES
)があります。 ARTISTS
テーブルからすべての詳細を取得し、アーティストごとに他のテーブルからのイメージ(どちらでもかまいません)を含めるクエリを生成したいと思います。
したがって、2つのテーブルをINNER JOIN
sするクエリが必要です。以下のクエリは、ARCHIVESCATALOGUE
テーブルからすべての結果、つまりアーティストごとの複数の結果を取得しています。ただし、アーティストごとに1つの結果のみが必要です。 artist.ArtistID
フィールドでDISTINCT
を使用しましたが、役に立ちませんでした。これがコードです:
SELECT DISTINCT artist.ArtistID
,ArchiveCatalogues.IMAGER
,ArchiveCatalogues.AUCTION
,artist.surname
,artist.firstnames
,artist.dates
,artist.honorific
,artist.biog
FROM artist
INNER JOIN ArchiveCatalogues ON (ArchiveCatalogues.ARTIST = artist.surname)
AND (ArchiveCatalogues.FIRSTNAME = artist.firstnames)
WHERE artist.surname >= H *
AND artist.surname < I
GROUP BY artist.surname
,artist.firstnames
,artist.dates
,artist.honorific
,artist.biog
,ArchiveCatalogues.AUCTION
,artist.ArtistID
,ArchiveCatalogues.IMAGER
おそらく、OUTER JOIN
を使用する必要がありますか?
まず(よくある誤解)、distinctは個々の列には適用されません。得られるのは、distinct行です。これはGROUP BY
とまったく同じであるため、distinctは冗長です。
第二に、あなたが興味のある(またはランダムなものを取得する)重複の中のどの行を決定する必要があります。ウィンドウ関数を使用して、アーティストごとにArchiveCataloguesを列挙することでこれを実現できます。
SELECT artist.ArtistID
,ArchiveCatalogues.IMAGER
,ArchiveCatalogues.AUCTION
,artist.surname
,artist.firstnames
,artist.dates
,artist.honorific
,artist.biog
, row_number() over (partition by artist.ArtistID
-- add wanted order her as:
-- order by ...
) as rn
FROM artist
JOIN ArchiveCatalogues
ON ArchiveCatalogues.ARTIST = artist.surname
AND ArchiveCatalogues.FIRSTNAME = artist.firstnames
WHERE artist.surname >= H *
AND artist.surname < I
目的がわからないので、グループを削除したことに注意してください。ここから最初の行を選択できます。
SELECT ArtistID
, IMAGER
, AUCTION
, surname
, firstnames
, dates
, honorific
, biog
FROM (
SELECT artist.ArtistID
,ArchiveCatalogues.IMAGER
,ArchiveCatalogues.AUCTION
,artist.surname
,artist.firstnames
,artist.dates
,artist.honorific
,artist.biog
, row_number() over (partition by artist.ArtistID
-- add wanted order her as:
-- order by ...
) as rn
FROM artist
JOIN ArchiveCatalogues
ON ArchiveCatalogues.ARTIST = artist.surname
AND ArchiveCatalogues.FIRSTNAME = artist.firstnames
WHERE artist.surname >= H *
AND artist.surname < I
) as T
WHERE rn = 1;
結合は奇妙に見えますが、テーブルとそれらのキーがどのように見えるかを知らなければ分からないでしょう。
DISTINCTは、クエリで次に配置した列だけでなく、SELECTステートメントのすべての列に適用されます。現在、DISTINCTとGROUP BYはまったく同じことを行っています。
あなたはグループ化によって本質的に言っています:
以下の組み合わせごとに1つのレコードが必要です。
artist.surname
,artist.firstnames
,artist.dates
,artist.honorific
,artist.biog
,ArchiveCatalogues.AUCTION
,artist.ArtistID
,ArchiveCatalogues.IMAGER
その特定の順序で。基本的に、一意のレコードと見なすものの疑似キーを作成しています。
「プライマリ」テーブルであるため、クエリは実際にはARTISTから結果を取得していますですが、これは、内部結合するテーブルであるため、ArchiveCataloguesテーブルに一致するレコードのみです(オン姓+名)。
他のテーブルと一致するかどうかに関係なく、両方のテーブルからレコードを探している場合は、FULL OUTER JOINを使用できますが、このシナリオではそれが必要だとは思いません。
ここでの問題は、クエリが必要な画像を知る方法がないため、関連するすべての画像が得られることです。 JOINに別のものを追加するか、GROUP関数を使用できます
簡単にするために、テーブルが見えないことを考えると、ArchiveCatalogueテーブルにはなんらかの一意の識別子が含まれていると想定するので、これを使用して行ごとに1つのイメージを選択できます。
SELECT artist.ArtistID
,ArchiveCatalogues.IMAGER
,ArchiveCatalogues.AUCTION
,artist.surname
,artist.firstnames
,artist.dates
,artist.honorific
,artist.biog
,MAX(ArchiveCatalogue.PRIMARYKEY)
FROM artist
INNER JOIN ArchiveCatalogues ON
ArchiveCatalogues.ARTIST = artist.surname AND
ArchiveCatalogues.FIRSTNAME = artist.firstnames
WHERE artist.surname >= H *
AND artist.surname < I
GROUP BY artist.ArtistID
,ArchiveCatalogues.IMAGER
,ArchiveCatalogues.AUCTION
,artist.surname
,artist.firstnames
,artist.dates
,artist.honorific
,artist.biog
MAX(Archive.Key)は、ID列の最大値を選択します。これは、最新の画像である可能性があります。 JOINでフィルタリングする方が効率的だと思いますが、これは読みやすいと思います