다른 열을 반환하면서 한 열에서 DISTINCT를 선택 하시겠습니까?


12

세 가지 조회 테이블을 사용하여 필요한 모든 정보를 얻는 쿼리가 있습니다. 나는이 필요 DISTINCT하지만 나는 또한 그것과 관련된 데이터의 휴식이 필요, 하나 개의 컬럼에 대한 값을.

내 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ᵀᴹ

답변:


7

아직 언급되지 않은 또 하나의 접근 방식은 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을 선택하여 "버림"으로 만 복제하기 때문에 데이터를 "고유"하게 만드는 것이 아닌 경우 하위 쿼리 외부에서 조인을 수행하는 것이 좋습니다.
Allan S. Hansen

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.