在一个列上选择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ᵀᴹ2012年

Answers:


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将其复制为仅“丢弃”。
艾伦·汉森

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

需要区分的列是什么?我将为您发布更全面的解决方案。
布朗斯通先生2012年

product.displayheading是专栏
stephmoreland,2012年

1

(我认为您想要做的是将每个结果行“折叠”为一个产品,因此,此答案就是基于这种假设。)

这是不可能的。要从其他表中获取相关的1 .. *数据,您必须在其他列中返回重复的值。

通常,处理此问题的方法是按原样运行查询,并处理应用程序代码中的合并结果集。我通常使用哈希收集方法来完成此操作,该方法以基于键值的集合中每种类型的不同实体结束。

尽管此方法确实会花费更多的网络流量,但通常最好执行一些操作,例如运行多个查询并将结果按需要在应用程序代码中组合在一起。它取决于许多因素,包括查询/查询运行的频率和返回多少数据。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.