2009-07-27 57 views
3

想象一下下面的架构和样本数据(SQL Server 2008中):变体使用GROUP BY子句中TSQL

OriginatingObject 
---------------------------------------------- 
ID 
1 
2 
3 

ValueSet 
---------------------------------------------- 
ID OriginatingObjectID DateStamp 
1 1      2009-05-21 10:41:43 
2 1      2009-05-22 12:11:51 
3 1      2009-05-22 12:13:25 
4 2      2009-05-21 10:42:40 
5 2      2009-05-20 02:21:34 
6 1      2009-05-21 23:41:43 
7 3      2009-05-26 14:56:01 

Value 
---------------------------------------------- 
ID ValueSetID Value 
1 1   28 
etc (a set of rows for each related ValueSet) 

我需要获得最新的ValueSet记录每个OriginatingObject的ID。不要认为记录的ID越高,越新。

我不知道如何正确使用GROUP BY,以确保组合在一起以形成每个聚合行的结果集包括具有该分组的最高DateStamp值的行的ID。我需要使用子查询还是有更好的方法?

+0

澄清:你想为每个OriginatingObjectID最近的ValueSet.ID? – Benjol 2009-07-27 11:34:18

+0

Benjol:对。 – 2009-07-27 11:36:14

回答

4

您可以使用相关子查询或IN使用多列和GROUP BY。

请注意,简单的GROUP-BY只能将您带入OriginatingIDs和时间戳列表。为了拉取相关的ValueSet ID,最干净的解决方案是使用子查询。

多列在GROUP-BY(可能更快):

SELECT O.ID, V.ID 
FROM Originating AS O, ValueSet AS V 
WHERE O.ID = V.OriginatingID 
AND 
(V.OriginatingID, V.DateStamp) IN 
(
    SELECT OriginatingID, Max(DateStamp) 
    FROM ValueSet 
    GROUP BY OriginatingID 
) 

相关子查询:

SELECT O.ID, V.ID 
FROM Originating AS O, ValueSet AS V 
WHERE O.ID = V.OriginatingID 
AND 
V.DateStamp = 
(
    SELECT Max(DateStamp) 
    FROM ValueSet V2 
    WHERE V2.OriginatingID = O.ID 
) 
+0

注意,如果您有两个最近的ValueSet具有完全相同的时间戳(但这可能是所需的行为),则这可能会返回重复的ViewSet。 – 2009-07-27 11:41:36

+1

......如果不是,Max(V.ID)和extra组将会足够。 – Benjol 2009-07-27 11:42:32

1
SELECT OriginatingObjectID, id 
FROM (
    SELECT id, OriginatingObjectID, RANK() OVER(PARTITION BY OriginatingObjectID 
            ORDER BY DateStamp DESC) as ranking 
    FROM ValueSet) 
WHERE ranking = 1; 
0

这可以用相关子查询来完成。不需要GROUP-BY。

SELECT 
    vs.ID, 
    vs.OriginatingObjectID, 
    vs.DateStamp, 
    v.Value 
FROM 
    ValueSet vs 
    INNER JOIN Value v ON v.ValueSetID = vs.ID 
WHERE 
    NOT EXISTS (
    SELECT 1 
    FROM ValueSet 
    WHERE OriginatingObjectID = vs.OriginatingObjectID 
      AND DateStamp > vs.DateStamp 
) 

只有当ValueSet表中的OriginatingObjectID不能有两个相等的DateStamps时,这才有效。