4

我有以下查询:

select vkbr.vkID, vkbr.bid, vkbr.Date, vkbr.agID 
FROM camp c (NOLOCK)
JOIN ag (NOLOCK) ON ag.campID = c.id
JOIN vkbr WITH (NOLOCK) ON vkbr.agID = ag.id
where c.id = 648322
order by vkbr.vkID;

结果如下:

vkID        bid     Date                    agID
1072845175  NULL    2012-12-04 20:20:12.390 16074852
1072845177  0.74    2012-12-01 23:36:11.280 16074852
1072845177  0.18    2012-12-02 23:01:26.123 16074852
1072845177  0.72    2012-12-09 23:38:52.503 16074852
1072845177  0.62    2012-12-14 15:26:49.643 16074852
1072845178  2.91    2012-12-08 19:37:00.877 16074852
1072845178  0.73    2012-12-13 17:54:11.240 16074852
1072845178  2.70    2012-12-14 15:26:49.643 16074852

我需要按 vkID 分组,获取 max(Date) 和 max(Date) 的出价以获得此结果:

1072845175  NULL    2012-12-04 20:20:12.390 16074852
1072845177  0.62    2012-12-14 15:26:49.643 16074852
1072845178  2.70    2012-12-14 15:26:49.643 16074852


select vkbr.vkID, MAX(vkbr.Date) as Date, MIN(vkbr.agID) as agID
FROM camp c (NOLOCK)
JOIN    ag (NOLOCK) ON ag.campID = c.id
JOIN    vkbr WITH (NOLOCK) ON vkbr.agID = ag.id
where c.id=648322
group by vkbr.vkID
having Max(vkbr.Date) is not null
and Max(Date) <= '2012-12-18';

由于我无法在 SELECT 语句中添加出价列 - 收到此错误:选择列表中的“出价”列无效,因为它不包含在聚合函数或 GROUP BY 子句中。

所以我尝试用临时表来做到这一点:

create table #getBids ( 
vkID bigint not null,
Date datetime null,
agID bigint null);

insert into #getBids (vkID, Date, agID) 
select vkbr.vkID, MAX(vkbr.Date) as Date, MIN(vkbr.agID) as agID
FROM camp c (NOLOCK)
JOIN    ag (NOLOCK) ON ag.campID = c.id
JOIN    vkbr WITH (NOLOCK) ON vkbr.agID = ag.id
where c.id = 648322
group by vkbr.vkID
having Max(vkbr.Date) is not null
and Max(Date) <= '2012-12-18';

Now this gives me the result I want:

select vkbr.vkID, vkbr.bid from vkbr
inner join #getBids on vkbr.Date = #getBids.Date
and vkbr.agID = #getBids.agID
and vkbr.vkID = #getBids.vkID

我想知道是否可以在一个查询中完成相同的结果而无需创建临时表?任何帮助是极大的赞赏。

4

3 回答 3

2

如果您使用的是 SQL Server 2005 或更高版本,您可以使用ROW_NUMBER()函数MAX(Date)为每个vkID.

我无法使用您的架构对此进行测试,但我认为它会像这样工作:

首先,声明一个公用表表达式 (CTE) 以在查询结果中添加行号

with cte as
(    
    select vkbr.vkID, vkbr.bid, vkbr.Date, vkbr.agID, ROW_NUMBER() OVER (PARTITION BY vkbr.vkID ORDER BY vkbr.Date DESC) AS RowNumber
    FROM camp c (NOLOCK)
    JOIN ag (NOLOCK) ON ag.campID = c.id
    JOIN vkbr WITH (NOLOCK) ON vkbr.agID = ag.id
    where c.id = 648322
)

那么,SELECT只有在哪里RowNumber = 1。这将为您提供每个的最新记录vkbr.vkID

select vkID, bid, Date, agID
from cte
where RowNumber = 1
于 2012-12-19T21:01:11.877 回答
1

询问:

SELECT vkbr.vkID,
       vkbr.bid,
       vkbr.Date,
       vkbr.agID
FROM camp c (NOLOCK)
JOIN ag (NOLOCK) ON ag.campID = c.id
JOIN vkbr WITH (NOLOCK) ON vkbr.agID = ag.id
WHERE c.id = 648322
AND vkbr.Date = (SELECT MAX(v.Date)
                 FROM vkbr v2
                 WHERE v2.vkID = vkbr.vkID
                 AND v2.agID = vkbr.agID)
ORDER BY vkbr.vkID

示例查询:

SQLFIDDLE示例

SELECT t1.*
FROM Table1 t1
WHERE t1.Date = (SELECT MAX(t2.Date)
                 FROM Table1 t2
                 WHERE t1.vkID = t2.vkID
                 AND t1.agID = t2.agID)

结果:

|       VKID |    BID |                            DATE |     AGID |
--------------------------------------------------------------------
| 1072845178 |   2.70 | December, 14 2012 15:26:49+0000 | 16074852 |
| 1072845177 |   0.62 | December, 14 2012 15:26:49+0000 | 16074852 |
| 1072845175 | (null) | December, 04 2012 20:20:12+0000 | 16074852 |
于 2012-12-19T21:24:09.927 回答
0

您可以通过一个查询来完成此操作。首先,查询必须通过 vkID 收集最大日期。接下来,它必须使用日期重新加入 vkbr 以获得实际出价。您可以使用sub-query,即类似这样的东西:

select vkID, bid, Date, agID
from
(
    select vkbr.vkID, MAX(vkbr.Date) as Date, MIN(vkbr.agID) as agID
    from camp c with (nolock)
    inner join ag with (nolock)
        on ag.campID = c.id
    inner join vkbr with (nolock)
        on vkbr.agID = ag.id
    where c.id = 648322
    group by vkbr.vkID
    having Max(vkbr.Date) is not null
    and Max(vkbr.Date) <= '2012-12-18';
) MaxDate
    inner join vkbr with (nolock)
        on vkbr.agID = MaxDate.agID
        and vkbr.Date = MaxDate.Date

我建议使用公用表表达式(CTE) 而不是子查询。CTE 方法看起来像这样:

;with MaxDate (vkID, Date, agID) as
(
    select vkbr.vkID, MAX(vkbr.Date) as Date, MIN(vkbr.agID) as agID
    from ...
)
select ...
from MaxDate
inner join vkbr
    on vkbr.agID = MaxDate.agID
    and vkbr.Date = MaxDate.Date
于 2012-12-19T20:55:38.500 回答