PILIH PERBEDAAN pada satu kolom, sambil mengembalikan kolom lainnya?

12

Saya punya pertanyaan yang menggunakan tiga tabel pencarian untuk mendapatkan semua informasi yang saya butuhkan. Saya perlu memiliki DISTINCTnilai untuk satu kolom, namun saya juga perlu sisa data yang terkait dengannya.

Kode SQL saya:

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;

Saya ingin mendapatkan semua produk dari permintaan ini, tetapi saya hanya ingin mendapatkannya sekali karena saya mengisi menu drop down untuk aplikasi pencarian. Saya ingin pengguna dapat memilih dari produk yang ada di tabel itu (itu sebabnya saya hanya perlu sekali).

Apakah ini terlalu rumit? Haruskah saya menggunakan pendekatan yang lebih sederhana?

stephmoreland
sumber
Tetapi suatu produk terkait dengan banyak dokumen. Dan permintaan Anda mengembalikan semuanya (dokumen untuk suatu produk). Yang mana yang harus dipilih?
ypercubeᵀᴹ

Jawaban:

7

Satu lagi pendekatan yang belum disebutkan adalah menggunakan fungsi jendela, misalnya 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
sumber
@ a1ex07- Terima kasih! Itu berhasil. Setiap kali saya mencoba mengadaptasi beberapa contoh dari internet, GABUNGAN saya yang membuat saya bingung, tetapi saya rasa saya mengerti sekarang.
stephmoreland
Akan lebih baik untuk melakukan penggabungan di luar subquery jika tidak apa yang membuat data "berbeda", untuk meminimalkan data yang Anda query dan duplikat hanya untuk "membuang" dengan memilih num = 1 dari fungsi jendela.
Allan S. Hansen
4

Ada beberapa cara untuk melakukan ini. Dua yang utama yang saya gunakan adalah ekspresi tabel umum dan sub-kueri. Menggunakan CTE, kueri Anda akan terlihat seperti ini:

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...*/

Atau menggunakan subquery:

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... */

Saya biasanya menguji untuk melihat mana yang lebih cepat dan pergi dengan yang itu.

Saya harap ini membantu Anda.

Mr.Brownstone
sumber
Saya pikir saya mengerti jawaban Anda, jadi saya mencobanya (yang pertama), tapi saya pikir GABUNGAN saya menyebabkan masalah dengan GABUNGAN solusi Anda.
stephmoreland
kolom apa yang perlu dibedakan? Saya akan memposting solusi yang lebih komprehensif untuk Anda.
Mr.Brownstone
product.displayheading adalah kolom
stephmoreland
1

(Saya pikir apa yang Anda coba lakukan adalah "runtuh" ​​setiap baris hasil ke satu produk, jadi jawaban ini sesuai dengan asumsi itu.)

Ini tidak mungkin. Untuk mendapatkan data 1 .. * terkait dari tabel lain, Anda harus mengembalikan nilai duplikat di kolom lainnya.

Secara umum cara untuk menangani ini adalah dengan menjalankan query sebagaimana adanya, dan memproses hasil gabungan yang ditetapkan dalam kode aplikasi. Saya biasanya melakukan ini menggunakan pendekatan pengumpulan hash yang berakhir dengan entitas yang berbeda dari setiap jenis dalam koleksi berdasarkan nilai kunci.

Meskipun pendekatan ini biayanya lebih mahal dalam hal lalu lintas jaringan, biasanya lebih baik melakukan sesuatu seperti menjalankan beberapa kueri dan menyatukan hasilnya seperti yang Anda butuhkan dalam kode aplikasi. Itu tergantung pada banyak faktor, termasuk seberapa sering kueri / kueri berjalan dan berapa banyak data yang dikembalikan.

Jon Seigel
sumber