不重复记录的SQL查询

13
我正在尝试构建一个查询,该查询将返回表中所有非重复(唯一)记录。该查询需要使用多个字段来确定记录是否重复。
例如,如果一个表具有以下字段:PKID、ClientID、Name、AcctNo、OrderDate、Charge,则我想使用AcctNo、OrderDate和Charge字段来查找唯一记录。
表格:
PKID-----ClientID-----Name-----AcctNo-----OrderDate-----Charge
1        JX100        John     12345      9/9/2010      $100.00
2        JX220        Mark     55567      9/9/2010       $23.00
3        JX690        Matt     89899      9/9/2010      $218.00
4        JX100        John     12345      9/9/2010      $100.00

查询的结果需要是:

PKID-----ClientID-----Name-----AcctNo-----OrderDate-----Charge
2        JX220        Mark     55567      9/9/2010       $23.00
3        JX690        Matt     89899      9/9/2010      $218.00

我尝试使用SELECT DISTINCT,但它无法起作用,因为它会在结果中保留重复记录中的一个。我还尝试使用HAVING COUNT = 1,但这会返回所有记录。

谢谢帮助。


你能展示一下你所使用的代码吗? - ptrcao
9个回答

14

HAVING COUNT(*) = 1 只有在你将用于查找唯一记录的字段包含在 GROUP BY 中时才有效。(即不包括 PKID,但是你可以使用 MAXMIN 返回它,因为在结果集中每个分组只有一条记录。)


好的,我再次使用COUNT = 1运行了查询,它成功了!由于某种原因,在之前运行时,它返回了所有记录。感谢您对正确方向的推动。 - nth

5
SELECT   MAX(PKID)     AS PKID    ,
         MAX(ClientID) AS ClientID,
         MAX(Name)     AS Name    ,
         AcctNo                   ,
         OrderDate                ,
         Charge
FROM     T
GROUP BY AcctNo   ,
         OrderDate,
         Charge
HAVING   COUNT(*) = 1

或者

SELECT PKID      ,
       ClientID  ,
       Name      ,
       AcctNo    ,
       OrderDate ,
       Charge
FROM   YourTable t1
WHERE  NOT EXISTS
       (SELECT *
       FROM    YourTable t2
       WHERE   t1.PKID     <> t2.PKID
       AND     t1.AcctNo    = t2.AcctNo
       AND     t1.OrderDate = t2.OrderDate
       AND     t1.Charge    = t2.Charge
       )

4
只需添加以下内容:
GROUP BY AcctNo, OrderDate, Charge
HAVING COUNT(1) = 1
< p > GROUP BY 将所有具有相同AcctNo、OrderDate和Charge的行分组在一起, 然后HAVING COUNT(1) = 1仅显示只有一个祖先的行。 < /p >

1
使用窗口函数进行计数,这样您就不必聚合字段。
select * from
(SELECT *,
count(*) over (partition by CLIENTID) as [Count]
from Table)
where Count=1

1

感谢kekekela给了我正确的方向。

这是产生我想要结果的查询:

SELECT AcctNo, OrderDate, Charge FROM Table1 GROUP BY AcctNo, OrderDate, Charge
HAVING (COUNT(AcctNo) = 1) AND (COUNT(OrderDate) = 1) AND (COUNT(Charge) = 1);

或者更简化一些,根据Gus的例子:

SELECT AcctNo, OrderDate, Charge FROM Table1 GROUP BY AcctNo, OrderDate, Charge
HAVING COUNT(1) = 1;

1
你可以直接删除PKID来返回所有记录:
SELECT DISTINCT 
           ClientID
         , Name
         , AcctNo
         , OrderDate
         , Charge
FROM       table;

注意: 这与您所要求的略有不同。
它通过删除一个非唯一字段来返回一个唯一集合。
根据您的示例,您要求返回非重复项。

我只能看到您的示例在尝试
通过提取“好”的记录来清理表格时才有用。


0

你可以先确定非唯一记录,然后测试那些不在该集合中的记录 - 就像这样

select * from mytable where pkid not in
(select t1.pkid 
from mytable t1 inner join mytable t2
on t1.pkid <> t2.pkid
and t1.acctno = t2.acctno
and t1.orderdate = t2.orderdate
and t1.charge = t2.charge)

内部查询的最后一部分允许您调整“相等”的条件-添加所需数量的列进行测试。 当然,如果没有主键,这将变得更加有趣 :) 在这种情况下,我通常会创建一个

Ketil


查询语句应该使用><而不是<>吗?使用<>,结果将不包含任何重复行,而不仅仅是一份副本。 - crizzis
不,<> 确保您不会针对自身测试记录 - 与 Martin Smith 的第二种解决方案相同。 < 或 > 只会查找具有更高或更低 pkid 值的 pkid 上的重复项 - 这还不足以确保指定数据列的唯一性。 - Ketil Duna

0
 SELECT GMPS.gen.ProductDetail.PaperType, GMPS.gen.ProductDetail.Size FROM
 GMPS.gen.ProductDetail GROUP BY GMPS.gen.ProductDetail.PaperType,
 GMPS.gen.ProductDetail.Size
 HAVING COUNT(1) = 1;

0
CREATE TABLE Employee (  
    EmployeeID CHAR(1),  
    FirstName VARCHAR2 (20),  
    LastName VARCHAR2 (20),  
    Salary NUMBER (8,2),  
    JoiningDate DATE,  
    Department VARCHAR2 (10),  
    Gender VARCHAR2 (6) 
);  

插入一些值

INSERT INTO Employee VALUES ('1', 'Vikas', 'Ahlawat', 60000.00, '15-Feb-2013', 'IT', 'Male');  
INSERT INTO Employee VALUES ('2', 'nikita', 'Jain', 53000.00, '09-Jan-2014', 'HR', 'Female');  
INSERT INTO Employee VALUES ('3', 'Ashish', 'Kumar', 100000.00, '09-Jan-2014', 'IT', 'Male');  
INSERT INTO Employee VALUES ('4', 'Nikhil', 'Shama', 48000.00, '09-Jan-2014', 'HR', 'Male');  
INSERT INTO Employee VALUES ('5', 'anish','kadian', 50000.00, '09-Jan-2014', 'Payroll', 'Male');  

-- 从上述表格(员工)中查找唯一的部门名称
SELECT Department FROM Employee  
GROUP BY Department  
HAVING COUNT(Department) = 1;  
  • 上述代码应该会给你返回唯一的部门名称,即“薪资支付”

你可以尝试修改一下上面的代码,来从其他字段中获取唯一的数据。例如:

SELECT Gender FROM Employee  
GROUP BY Gender  
HAVING COUNT(Gender) = 1;  

应该将其翻译为“女性”,因为它仅在性别字段中使用一次。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接