web-dev-qa-db-ja.com

Distinctを使用してテーブルから一意のレコードを1つだけ選択する方法

私のテーブルには、同じMemberIDを持つ複数のレコードがあります。 1つのレコードだけを作成したい。

select DISTINCT(MemberID)  from AnnualFees;

その後、結果が来ます。しかし、他の列データも表示したいのですが、これを行うと

select DISTINCT(MemberID),StartingDate,ExpiryDate,Amount  from AnnualFees;

同じMemberIDデータを含むすべての詳細も表示されます。

誰かが私を助けることができますか?.

8
Nubkadiya

これを実行できるよりも、各メンバーIDに対してランダムに任意の行が必要であると仮定します。

select memberid, this, that, theother
from
(
select memberid, this, that, theother,
       row_number() over (partition by memberid order by this) rn
from   annualfees
)
where rn = 1;

メンバーIDごとに特定の行が必要な場合(例:最新のStartDateを持つものは、次のように変更できます。

select memberid, this, that, theother
from
(
select memberid, this, that, theother,
       row_number() over (partition by memberid order by StartDate desc) rn
from   annualfees
)
where rn = 1;
21
Tony Andrews

これが必要なものかどうかはわかりませんが、DISTINCTではなくGROUPBYを確認する必要があるかもしれません...

同じメンバーIDを持つレコードが複数ある場合は、必要なレコードを他のレコードから識別する方法を正確に指定する必要がある場合があります

例:各メンバーの最終開始日を取得する:

SELECT memberid, max(startingdate)
FROM annualfees
GROUP BY memberid

しかし、この種の方法で1つのレコードを識別し、他の列も表示する必要がある場合は、 このようなトリックを行う必要があるかもしれません ...

たとえば、上記のSELECTを結合でサブクエリして、必要な他の列を結合します:

SELECT subq.memid, subq.startdate, a.expirydate, a.amount
FROM (
  SELECT memberid AS memid, max(startingdate) AS startdate
  FROM annualfees
  GROUP BY memberid ) subq
INNER JOIN annualfees a ON a.memberid = subq.memid 
               AND a.startingdate = subq.startdate

最初から最後まで、データテーブルも表示されます(o/pは "SET VERIFY ON"を使用してトレース/取得されました)...

-- show all rows
select *
from annualfees
order by memberid, startingdate
MEMBERID               STARTINGDATE              EXPIRYDATE           AMOUNT               
---------------------- ------------------------- -------------------- -------------------- 
1                      02-DEC-09                 05-FEB-10            111                  
1                      25-JUN-10                 25-JUN-11            222                  
2                      25-APR-10                 25-JUN-13            333                  

3 rows selected

/
-- show one member`s data using max(startingdate) as selector.
SELECT memberid, max(startingdate)
    FROM annualfees
    GROUP BY memberid
MEMBERID               MAX(STARTINGDATE)         
---------------------- ------------------------- 
1                      25-JUN-10                 
2                      25-APR-10                 

2 rows selected

/ 
-- show above data joined with the other columns.
SELECT subq.memid, subq.startdate, a.expirydate, a.amount
    FROM (
      SELECT memberid AS memid, max(startingdate) AS startdate
      FROM annualfees
      GROUP BY memberid ) subq
    INNER JOIN annualfees a ON a.memberid = subq.memid AND a.startingdate = subq.startdate
MEMID                  STARTDATE                 EXPIRYDATE           AMOUNT               
---------------------- ------------------------- -------------------- -------------------- 
1                      25-JUN-10                 25-JUN-11            222                  
2                      25-APR-10                 25-JUN-13            333                  

2 rows selected

/
6
MarkyBoyMark

何らかの方法で返すMemberIDが重複している行を選択する必要があります。これにより、startingDateが最大の行が取得されます。

SELECT MemberID,StartingDate,ExpiryDate,Amount 
FROM AnnualFees af
WHERE NOT EXISTS (
        SELECT * from AnnualFees af2 
        WHERE af2.MemberID = af.MemberID 
        AND af2.StartingDate > af.StartingDate)
3
Martin Smith