2010-09-10 149 views
7

我试图构建一个查询,它将返回表中的所有非重复(唯一)记录。查询将需要使用多个字段来确定记录是否重复。非重复记录的SQL查询

例如,如果一个表具有以下字段; 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,但是它返回所有记录。

感谢您的帮助。

回答

8

HAVING COUNT(*) = 1将工作,如果您只包括GROUP BY中用于查找唯一记录的字段。 (即不PKID,但你可以使用MAXMIN返回,既然你只有在结果集每组一个记录。)

+0

OK,我跑的查询再次使用COUNT = 1和它的工作!出于某种原因,当我之前运行它时,它返回了所有记录。感谢您将它推向正确的方向。 – nth 2010-09-10 16:06:52

+0

太棒了,很高兴你能工作! – heisenberg 2010-09-10 16:16:46

4
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 
     ) 
2

只需添加:

GROUP BY AcctNo, OrderDate, Charge 
HAVING COUNT(1) = 1 

GROUP BY基团与同一AcctNo,订购日期和充电的所有行一起, 则HAVING COUNT(1) = 1只显示只有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); 

以上,基于格斯的例子简化:

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

你可以只下降了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

+0

不应该查询读取'>'或'<'而不是'<>'?用'<>'结果将包含* none *的重复行而不是一个副本 – crizzis 2017-06-14 17:30:20

+0

不,<>确保您不会对自己测试记录 - 与Martin Smiths解决方案#2相同。 A < or >只会在pkid值较高或较低的pkids上查找重复项 - 不足以确保指定的数据列的唯一性。 – 2017-06-16 04:54:32

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;