DISTINCT只有一列

时间:2011-02-16 20:23:19

标签: sql sql-server

假设我有以下问题。

SELECT ID, Email, ProductName, ProductModel FROM Products

如何修改它以使其不返回重复的电子邮件?

换句话说,当多行包含相同的电子邮件时,我希望结果只包含其中一行(最好是最后一行)。应允许其他列中的重复项。

DISTINCTGROUP BY等条款似乎适用于整行。所以我不确定如何处理这个问题。

8 个答案:

答案 0 :(得分:161)

如果您使用的是SQL Server 2005或更高版本,请使用以下命令:

SELECT *
  FROM (
                SELECT  ID, 
                        Email, 
                        ProductName, 
                        ProductModel,
                        ROW_NUMBER() OVER(PARTITION BY Email ORDER BY ID DESC) rn
                    FROM Products
              ) a
WHERE rn = 1

编辑: 使用where子句的示例:

SELECT *
  FROM (
                SELECT  ID, 
                        Email, 
                        ProductName, 
                        ProductModel,
                        ROW_NUMBER() OVER(PARTITION BY Email ORDER BY ID DESC) rn
                    FROM Products
                   WHERE ProductModel = 2
                     AND ProductName LIKE 'CYBER%'

              ) a
WHERE rn = 1

答案 1 :(得分:10)

这假设SQL Server 2005+并且您对“last”的定义是给定电子邮件的最大PK

;WITH CTE AS
(
SELECT ID, 
       Email, 
       ProductName, 
       ProductModel, 
       ROW_NUMBER() OVER (PARTITION BY Email ORDER BY ID DESC) AS RowNumber 
FROM   Products
)
SELECT ID, 
       Email, 
       ProductName, 
       ProductModel
FROM CTE 
WHERE RowNumber = 1

答案 2 :(得分:6)

您可以使用GROUP BY功能

SELECT ID, Email, ProductName, ProductModel FROM Products GROUP BY Email

答案 3 :(得分:5)

当您使用DISTINCT时,将其视为一个独特的行,而不是列。它只会返回列不完全相同的行。

SELECT DISTINCT ID, Email, ProductName, ProductModel
FROM Products

----------------------
1 | something@something.com | ProductName1 | ProductModel1
2 | something@something.com | ProductName1 | ProductModel1

查询将返回两行,因为ID列不同。我假设ID列是一个递增的IDENTITY列,如果你想返回最后一列那么我推荐这样的东西:

SELECT DISTINCT TOP 1 ID, Email, ProductName, ProductModel
FROM Products
ORDER BY ID DESC

TOP 1将仅返回第一条记录,通过ID降序排序,它将返回最后一行的结果。这将为您提供最后一条记录。

答案 4 :(得分:0)

对于Access,您可以使用我在此处提供的SQL Select查询:

例如,您有此表:

CLIENTE || NOMBRES || MAIL

888 || T800 ARNOLD || t800.arnold@cyberdyne.com

123 || JOHN CONNOR || s.connor@skynet.com

125 || SARAH CONNOR ||s.connor@skynet.com

您只需要选择不同的邮件。 你可以这样做:

SQL SELECT:

SELECT MAX(p.CLIENTE) AS ID_CLIENTE
, (SELECT TOP 1 x.NOMBRES 
    FROM Rep_Pre_Ene_MUESTRA AS x 
    WHERE x.MAIL=p.MAIL 
     AND x.CLIENTE=(SELECT MAX(l.CLIENTE) FROM Rep_Pre_Ene_MUESTRA AS l WHERE x.MAIL=l.MAIL)) AS NOMBRE, 
p.MAIL
FROM Rep_Pre_Ene_MUESTRA AS p
GROUP BY p.MAIL;

您可以使用它来选择最大ID,该最大ID的对应名称,您可以添加任何其他属性。然后在最后你将不同的列放到过滤器中,你只将它与最后一个不同的列组合在一起。

这将为您提供相应数据的最大ID,您可以使用min或任何其他功能,并将该功能复制到子查询。

此选择将返回:

CLIENTE || NOMBRES || MAIL

888 || T800 ARNOLD || t800.arnold@cyberdyne.com

125 || SARAH CONNOR ||s.connor@skynet.com

请记住为您选择的列编制索引,并且distinct列必须没有大写或小写的数字数据,否则它将无效。 这也只适用于一个挂号邮件。 快乐的编码!!!

答案 5 :(得分:0)

试试这个

;With Tab AS (SELECT DISTINCT Email FROM  Products)
SELECT Email,ROW_NUMBER() OVER(ORDER BY Email ASC) AS  Id FROM Tab
ORDER BY Email ASC

答案 6 :(得分:-1)

DISTINCTGROUP BY处理整行的原因是您的查询返回整行。

为了帮助您理解:尝试手动写出查询应该返回的内容,您将看到在非重复列中放置什么是不明确的。

如果您确实不关心其他列中的内容,请不要返回它们。为每个电子邮件地址返回一个随机行似乎对我来说没用。

答案 7 :(得分:-1)

尝试一下:

SELECT ID, Email, ProductName, ProductModel FROM Products WHERE ID IN (SELECT MAX(ID) FROM Products GROUP BY Email)