2010-06-25 14 views
6

la mia tabella ha più record che ha lo stesso MemberID. Voglio ottenere solo un record.Come selezionare un solo record univoco dal Table using Distinct

select DISTINCT(MemberID) from AnnualFees; 

quindi il risultato arriverà. ma io voglio mostrare gli altri dati della colonna anche, ma quando faccio questo

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

tutti i dettagli, tra cui i dati stessi memberId anche la visualizzazione.

qualcuno può aiutarmi.

+0

Quindi, come si desidera scegliere QUALE delle molte righe di AnnualFees per MemberID = 123 deve essere visualizzato? O vuoi solo una riga a caso? –

risposta

18

Supponendo che si desidera solo una riga a caso per ogni memberId di quanto si può fare questo:

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; 

Se si voleva una riga specifica per ogni memberId, per esempio quello con la più recente StartDate allora si potrebbe modificarlo per:

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; 
+0

RE: la tua ultima query. Ti capita di sapere se questo è più efficiente in Oracle rispetto alla versione nella mia risposta? –

+1

@Martin Smith: la soluzione di analisi (Tony's) eseguirà un singolo passaggio sui dati mentre il tuo aggiungerà un self-join (che potrebbe essere un piccolo overhead, ma aggiungerà comunque lavoro). ** In generale **, la soluzione di Tony sarà quindi più efficiente. –

+0

@Vincent Grazie, mi chiedevo il calcolo numero_riga. Presumo che nel singolo passaggio sia necessario creare un bucket per ogni membro membro, riempirlo con date di inizio e ID di riga e quindi ordinare ciascun bucket. Se è così posso vedere che sarebbe più veloce. Se questa ipotesi su come funziona è totalmente sbagliata qualcuno me lo faccia sapere! –

-3

selezionare DISTINCT MemberID, StartingDate, ExpiryDate, importo da AnnualFees;

rimuovere paranthesis

+2

Ciò restituirà una riga per * ogni permutazione * di MemberID, StartingDate, ExpiryDate e Amo – APC

3

è necessario selezionare quale delle righe con MemberIDs duplicate per tornare in qualche modo. Questo otterrà la riga con il più grande data di inizio.

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) 
5

non so se questo è abbastanza quello che ti serve, ma potrebbe essere necessario guardare GROUP BY invece di DISTINCT ...

se si dispone di diversi record con lo stesso ID membro, potrebbe essere necessario specificare exaclty come identificare quella desiderata dagli altri

ad esempio per ottenere ogni data Membro`s ultima partenza:

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

ma se è necessario identificare un record in questo tipo di modo, ma visualizzare anche le altre colonne, penso you may need to do some trickery like this ...

ad esempio sub-query sopra Seleziona con un iscriverti per unirsi agli altri colonne che si vogliono:

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 

dall'inizio alla fine, anche mostrando tabella di dati (o/p è stato rintracciato/afferrato con "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 

/
Problemi correlati