2010-08-09 30 views
16

tengo una tabla que tiene las siguientes columnasservidor SQL seleccionar filas distintas utilizando más valor Recientes sólo

  • Id
  • ForeignKeyId
  • AttributeName
  • AttributeValue
  • Creado

Algunos de los datos pueden verse así:

1, 1, 'EmailPreference', 'Text', 1/1/2010 
2, 1, 'EmailPreference', 'Html', 1/3/2010 
3, 1, 'EmailPreference', 'Text', 1/10/2010 
4, 2, 'EmailPreference', 'Text', 1/2/2010 
5, 2, 'EmailPreference', 'Html', 1/8/2010 

me gustaría ejecutar una consulta que extrae el valor más reciente de la columna de AttributeValue distinta para cada ForeignKeyId andAttributeName, utilizando la columna Creado para determinar el valor más reciente. Ejemplo de salida sería:

ForeignKeyId AttributeName AttributeValue Created 
------------------------------------------------------- 
1   'EmailPreference' 'Text'   1/10/2010 
2   'EmailPreference' 'Html'   1/8/2010 

¿Cómo puedo hacer esto con SQL Server 2005?

+0

¿No debería el valor ser 3, no 1, para EmailPreference/Text/1/10/2010? –

+0

No, la primera columna en el resultado es la ID de la clave externa, no la Id. De la fila – Chris

Respuesta

18

Una forma

select t1.* from (select ForeignKeyId,AttributeName, max(Created) AS MaxCreated 
from YourTable 
group by ForeignKeyId,AttributeName) t2 
join YourTable t1 on t2.ForeignKeyId = t1.ForeignKeyId 
and t2.AttributeName = t1.AttributeName 
and t2.MaxCreated = t1.Created 

Véase también Including an Aggregated Column's Related Values para 5 diferentes maneras de hacer este tipo de consulta

+0

Ese es un enlace informativo. ¡Gracias! –

9

Uso:

SELECT x.foreignkeyid, 
     x.attributename, 
     x.attributevalue, 
     x.created 
    FROM (SELECT t.foreignkeyid, 
       t.attributename, 
       t.attributevalue, 
       t.created, 
       ROW_NUMBER() OVER (PARTITION BY t.foreignkeyid, t.attributename 
             ORDER BY t.created DESC) AS rank 
      FROM TABLE t) x 
WHERE x.rank = 1 

Usando un CTE:

WITH summary AS (
    SELECT t.foreignkeyid, 
      t.attributename, 
      t.attributevalue, 
      t.created, 
      ROW_NUMBER() OVER (PARTITION BY t.foreignkeyid, t.attributename 
            ORDER BY t.created DESC) AS rank 
     FROM TABLE t) 
SELECT x.foreignkeyid, 
     x.attributename, 
     x.attributevalue, 
     x.created 
    FROM summary x 
WHERE x.rank = 1 

También:

SELECT t.foreignkeyid, 
     t.attributename, 
     t.attributevalue, 
     t.created 
    FROM TABLE t 
    JOIN (SELECT x.foreignkeyid, 
       x.attributename, 
       MAX(x.created) AS max_created 
      FROM TABLE x 
     GROUP BY x.foreignkeyid, x.attributename) y ON y.foreignkeyid = t.foreignkeyid 
               AND y.attributename = t.attributename 
               AND y.max_created = t.created 
Cuestiones relacionadas