2010-08-09 10 views
16

Ich habe eine Tabelle, die die folgenden SpaltenSQL Server auswählen unterschiedliche Zeilen letzten Wert mit nur

  • Id
  • hat ForeignKeyId
  • Attribut
  • Attribute
  • Erstellt

Einige der Daten können wie folgt aussehen:

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 

Ich möchte eine Abfrage auszuführen, die den aktuellsten Wert der Attributwert Spalte für jede einzelne ForeignKeyId andAttributeName zieht, die Erstellt Spalte den aktuellsten Wert zu bestimmen. Beispiel Ausgabe wäre:

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

Wie kann ich die SQL Server 2005 zu tun?

+0

Sollte der Wert nicht 3 sein, nicht 1, für die EmailPreference/Text/1/10/2010? –

+0

Nein, die erste Spalte in der Ausgabe ist die Fremdschlüssel-ID, nicht die Zeilen-ID – Chris

Antwort

18

Ein Weg

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 

Siehe auch Including an Aggregated Column's Related Values für 5 verschiedene Möglichkeiten, diese Art von Abfrage zu tun

+0

Das ist ein informativer Link. Vielen Dank! –

9

Verwendung:

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 

WAK Verwendung:

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 

Auch:

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