2010-06-25 5 views
6

mi tabla tiene varios registros que tienen el mismo ID de miembro. quiero dar como resultado solo un registro.Cómo seleccionar solo un registro único de la tabla usando Distintivo

select DISTINCT(MemberID) from AnnualFees; 

entonces el resultado vendrá. pero quiero mostrar la otra columna de datos también, pero cuando hago esto

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

todos los detalles, incluyendo mismos datos memberID también se presentan.

alguien me puede ayudar.

+0

Entonces, ¿cómo desea elegir ¿CUÁL de las tantas filas de AnnualFees para MemberID = 123 debería mostrarse? ¿O solo quieres una fila al azar? –

Respuesta

18

Suponiendo que lo que desea cualquier fila al azar para cada memberId de lo que puede hacer esto:

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; 

Si querías una fila específica por memberId, por ejemplo, el que tiene el más reciente StartDate entonces usted podría modificarlo para:

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: Su última consulta. ¿Sabes por casualidad si es más eficiente en Oracle que la versión en mi respuesta? –

+1

@Martin Smith: la solución de análisis (de Tony) realizará una única transferencia de datos, mientras que la suya agregará una autocombinación (que puede ser una pequeña sobrecarga, pero agregará trabajo de todos modos). ** En general **, la solución de Tony será, por lo tanto, más eficiente. –

+0

@Vincent Gracias, me preguntaba sobre el cálculo row_number. Supongo que en una sola pasada debe crear un depósito para cada memberid, completarlo con las fechas de inicio y las identificaciones de filas, y luego ordenar cada depósito. Si es así, puedo ver que sería más rápido. Si esta suposición sobre cómo funciona es totalmente incorrecto, ¡alguien me avise! –

-3

seleccione DISTINCT MemberID, StartingDate, ExpiryDate, Monto de AnnualFees;

quitar un paréntesis

+2

Esto devolverá una fila para * cada permutación * de MemberID, StartingDate, ExpiryDate y Amount – APC

3

Usted deberá seleccionar cuál de las filas duplicadas con MemberIDs para volver de alguna manera. Esto obtendrá la fila con mayor fecha de inicio.

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

no saben si esto es exactamente lo que necesita, pero puede que tenga que mirar a GROUP BY en lugar de DISTINCT ...

si tiene varios registros con el mismo ID de miembro, es posible que tenga que especificar exaclty cómo identificar el que desee de los otros

por ejemplo, para obtener cada fecha del miembro última partida:

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

pero si usted necesita para identificar un registro de este tipo de forma, sino también mostrar las otras columnas, creo you may need to do some trickery like this ...

por ejemplo, sub-consulta lo anterior SELECT con una unión para unirse a la otra columnas que desea:

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 

de principio a fin, mostrando también la tabla de datos (O/P fue rastreado/agarrado usando "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 

/
Cuestiones relacionadas