web-dev-qa-db-ja.com

重複しないレコードの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を使用してみましたが、重複するレコードの1つが結果に保持されるため、機能しません。 HAVING COUNT = 1も使用してみましたが、すべてのレコードが返されます。

助けてくれてありがとう。

8
nth

HAVING COUNT(*) = 1は、一意のレコードを見つけるために使用しているGROUP BYのフィールドのみを含める場合に機能します。 (つまり、PKIDではありませんが、結果セットのグループごとに1つのレコードしかないため、MAXまたはMINを使用してそれを返すことができます。)

9
heisenberg
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
Martin Smith

単に追加します:

_GROUP BY AcctNo, OrderDate, Charge
HAVING COUNT(1) = 1
_

_GROUP BY_は、同じAcctNo、OrderDate、およびChargeを持つすべての行をグループ化し、HAVING COUNT(1) = 1は、前駆体が1つしかない行のみを表示します。

3
Gus

正しい方向にナッジしてくれた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
nth
 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
waqas ahmad

PKIDをドロップするだけで、すべてのレコードを返すことができます。

SELECT DISTINCT 
           ClientID
         , Name
         , AcctNo
         , OrderDate
         , Charge
FROM       table;

注:これはあなたが求めているものとは少し異なります。
1つの一意でないフィールドを削除することにより、一意のセットを返します。
あなたの例では、重複していないものを返すように求めています。

私はあなたがしようとしている場合にのみあなたの例が役立つのを見ることができました
「適切な」レコードを抽出してテーブルをクリーンアップします。

0
vol7ron

最初に一意でないレコードを判別してから、そのセットにないレコードをテストすることができます-このように

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)

内部クエリの最後の部分では、「同等」の基準をいじることができます。テストする必要な列数を追加します。もちろん、これはその主キーがないともっと面白くなります:)そのような場合、私は通常それを作成することになります

ケチル

0
Ketil Duna