Diğer sütunları döndürürken bir sütunda DISTINCT SEÇİLİR Mİ?


12

İhtiyacım olan tüm bilgileri almak için üç arama tabloları kullanan bir sorgu var. Ben de DISTINCTbir sütun için değerleri olması gerekir , ancak ben de onunla ilişkili verilerin geri kalanı gerekir.

SQL kodum:

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;

Bu sorgudan tüm ürünleri almak istiyorum ama sadece bir kez almak istiyorum çünkü bir arama uygulaması için açılır menü dolduruyorum. Kullanıcının bu tablodaki ürünler arasından seçim yapabilmesini istiyorum (bu yüzden onlara sadece bir kez ihtiyacım var).

Bu çok karmaşık mı? Daha basitleştirilmiş bir yaklaşım kullanmalı mıyım?


Ancak bir ürün birçok belgeyle ilgilidir. Sorgunuz hepsini döndürür (bir ürün için belgeler). Hangisi seçilmeli?
ypercubeᵀᴹ

Yanıtlar:


7

Henüz bahsedilmeyen bir yaklaşım daha pencere işlevlerini kullanmaktır, örneğin 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- Teşekkürler! İşe yaradı. İnternetten bir örnek uyarlamaya çalıştığımda, kafamı karıştıran JOINS'imdi, ama sanırım şimdi anladım.
stephmoreland

Sorguladığınız verileri en aza indirgemek ve yalnızca pencere işlevinden num = 1 seçerek "atmak" için çoğaltmak için verileri "ayrı" yapan şey değilse alt sorgunun dışında birleştirmeleri yapmak daha iyi olur.
Allan S. Hansen

4

Bunu yapmanın birkaç yolu vardır. Kullandığım iki ana ortak tablo ifadeleri ve alt sorgulardır. Bir CTE kullanmak, sorgunuz şöyle görünecektir:

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

Veya bir alt sorgu kullanarak:

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

Normalde hangisinin daha hızlı olduğunu test edip onunla devam ediyorum.

Umarım bu sana yardımcı olur.


Cevabınızı anladığımı sanıyordum, bu yüzden denedim (birincisi), ancak sanırım JOINS, çözümünüzün JOINS ile ilgili bir soruna neden oluyor.
stephmoreland

belirgin olması gereken sütun nedir? Sizin için daha kapsamlı bir çözüm göndereceğim.
Mr.Brownstone

product.displayheading sütundur
stephmoreland

1

(Sanırım yapmaya çalıştığınız şey, her bir sonuç satırını tek bir ürüne "daraltmak", bu nedenle bu yanıt bu varsayımı sürdürüyor.)

Bu mümkün değil. Diğer tablolardan ilgili 1 .. * verilerini almak için, diğer sütunlara yinelenen değerler döndürmeniz gerekir.

Genellikle bunu işlemenin yolu sorguyu olduğu gibi çalıştırmak ve birleştirilmiş sonuç kümesini uygulama kodunda işlemektir. Bunu genellikle bir anahtar değerine dayanan bir koleksiyondaki her türden farklı varlıklarla sonuçlanan bir karma toplama yaklaşımı kullanarak yaparım.

Bu yaklaşım ağ trafiği açısından daha pahalı olsa da, genellikle birden fazla sorgu çalıştırmak ve sonuçları uygulama kodunda istediğiniz gibi birleştirmek gibi bir şey yapmak tercih edilir. Sorgunun / sorguların ne sıklıkta çalıştırıldığı ve ne kadar veri döndürüldüğü de dahil olmak üzere birçok faktöre bağlıdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.