1つの列でDISTINCTを選択し、他の列を返しますか?


12

3つのルックアップテーブルを使用して必要なすべての情報を取得するクエリがあります。私が持っている必要がありますDISTINCTが、私もそれに関連するデータの残りを必要とする、1列の値を。

私のSQLコード:

SELECT acss_lookup.ID AS acss_lookupID,
   acss_lookup.product_lookupID AS acssproduct_lookupID,
   acss_lookup.region_lookupID AS acssregion_lookupID,
   acss_lookup.document_lookupID AS acssdocument_lookupID,
   product.ID AS product_ID,
   product.parent_productID AS productparent_product_ID,
   product.label AS product_label,
   product.displayheading AS product_displayheading,
   product.displayorder AS product_displayorder,
   product.display AS product_display,
   product.ignorenewupdate AS product_ignorenewupdate,
   product.directlink AS product_directlink,
   product.directlinkURL AS product_directlinkURL,
   product.shortdescription AS product_shortdescription,
   product.logo AS product_logo,
   product.thumbnail AS product_thumbnail,
   product.content AS product_content,
   product.pdf AS product_pdf,
   product.language_lookupID AS product_language_lookupID,
   document.ID AS document_ID,
   document.shortdescription AS document_shortdescription,
   document.language_lookupID AS document_language_lookupID,
   document.document_note AS document_document_note,
   document.displayheading AS document_displayheading
FROM acss_lookup
     INNER JOIN product ON (acss_lookup.product_lookupID = product.ID)
     INNER JOIN document ON (acss_lookup.document_lookupID = document.ID)
ORDER BY product_displayheading ASC;

このクエリからすべての製品を取得したいのですが、検索アプリケーションのドロップダウンメニューにデータを入力しているため、一度だけ取得したいです。ユーザーがそのテーブルにある製品から選択できるようにしたいのです(だから、必要なのは一度だけです)。

これは複雑すぎますか?もっと単純なアプローチを使用する必要がありますか?


しかし、製品は多くのドキュメントに関連しています。そして、クエリはそれらすべて(製品のドキュメント)を返します。どちらを選ぶべきですか?
ypercubeᵀᴹ

回答:


6

まだ言及されていないもう1つのアプローチは、row_numberなどのウィンドウ関数を使用することです。

   SELECT * FROM  
   (
   SELECT acss_lookup.ID AS acss_lookupID, 
   ROW_NUMBER() OVER 
   (PARTITION BY your_distinct_column ORDER BY any_column_you_think_is_appropriate)
   as num,
   acss_lookup.product_lookupID AS acssproduct_lookupID,
   acss_lookup.region_lookupID AS acssregion_lookupID,
   acss_lookup.document_lookupID AS acssdocument_lookupID,
   product.ID AS product_ID,
   product.parent_productID AS productparent_product_ID,
   product.label AS product_label,
   product.displayheading AS product_displayheading,
   product.displayorder AS product_displayorder,
   product.display AS product_display,
   product.ignorenewupdate AS product_ignorenewupdate,
   product.directlink AS product_directlink,
   product.directlinkURL AS product_directlinkURL,
   product.shortdescription AS product_shortdescription,
   product.logo AS product_logo,
   product.thumbnail AS product_thumbnail,
   product.content AS product_content,
   product.pdf AS product_pdf,
   product.language_lookupID AS product_language_lookupID,
   document.ID AS document_ID,
   document.shortdescription AS document_shortdescription,
   document.language_lookupID AS document_language_lookupID,
   document.document_note AS document_document_note,
   document.displayheading AS document_displayheading
   FROM acss_lookup
     INNER JOIN product ON (acss_lookup.product_lookupID = product.ID)
     INNER JOIN document ON (acss_lookup.document_lookupID = document.ID)
   )a
   WHERE a.num = 1
   ORDER BY product_displayheading ASC;

@ a1ex07-ありがとう!うまくいきました。私がネットからいくつかの例を適応しようとするたびに、私は混乱させられたのは私のJOINSでしたが、私は今それを手に入れたと思います。
stephmoreland

ウィンドウ関数からnum = 1を選択して、クエリするデータを最小化し、「捨てる」だけに複製するために、データを「区別」するものではない場合、サブクエリの外部で結合を行う方が良いでしょう。
アランS.ハンセン

4

これを行うにはいくつかの方法があります。私が使用する主なものは、一般的なテーブル式とサブクエリです。CTEを使用すると、クエリは次のようになります。

WITH theResultSet AS
(
    SELECT DISTINCT(column) AS col1 FROM some.table
)
SELECT whatever
  FROM more.data AS a
  JOIN theResultSet as b ON a.col1 = b.col1
  /* additional joins, clauses etc...*/

または、サブクエリを使用します。

SELECT whatever
  FROM more.data AS a
  JOIN (SELECT DISTINCT(column) AS col1 FROM some.table) AS b ON a.col1 = b.col1
/* additional joins, clauses etc... */

私は通常、どちらが高速であるかを確認し、それに合わせてテストします。

これがあなたのお役に立てば幸いです。


私はあなたの答えを理解したと思ったので、それを試しました(最初のもの)が、私のJOINSがあなたのソリューションのJOINSに問題を引き起こしていると思います。
stephmoreland

区別する必要がある列は何ですか?より包括的なソリューションを掲載します。
Mr.Brownstone

product.displayheadingは列です
stephmoreland

1

(あなたがやろうとしていることは、各結果行を単一の製品に「折りたたむ」ことだと思うので、この答えはその仮定に基づいています。)

これは不可能です。他のテーブルから関連する1 .. *データを取得するには、他の列に重複した値を返す必要があります。

通常、これを処理する方法は、クエリをそのまま実行し、結合された結果セットをアプリケーションコードで処理することです。私は通常、キー値に基づいてコレクション内の各タイプの個別のエンティティになるハッシュコレクションアプローチを使用してこれを行います。

このアプローチはネットワークトラフィックの点ではよりコストがかかりますが、通常、複数のクエリを実行し、アプリケーションコードで必要に応じて結果をつなぎ合わせるようなものを行うよりも望ましい方法です。クエリ/クエリの実行頻度や返されるデータ量など、多くの要因に依存します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.