我必须查询几毫秒行的表,我想做最优化的表.
让我们想要通过多个放映室来控制对电影院的访问,并将其保存为:
AccessRecord
(TicketId,
TicketCreationTimestamp,
TheaterId,
ShowId,
MovieId,
SeatId,
CheckInTimestamp)
为简化起见,数据类型’bigint’和’Timestamp’的’Id’列是’datetime’.门票随时出售,人们随机进入剧院.主键(也是唯一的)是TicketId.
我想获取每个电影和剧院,并显示(时间)访问剧院的第一个和最后一个人看到一个mov的AccessRecord信息.如果两个签到同时发生,我只需要1,其中任何一个.
我的解决方案是在子查询中连接PK和分组列以获取行:
select
AccessRecord.*
from
AccessRecord
inner join(
select
MAX(CONVERT(nvarchar(25),CheckInTimestamp, 121) + CONVERT(varchar(25), TicketId)) as MaxKey,
MIN(CONVERT(nvarchar(25),CheckInTimestamp, 121) + CONVERT(varchar(25), TicketId)) as MinKey
from
AccessRecord
group by
MovieId,
TheaterId,
ShowId
) as MaxAccess
on CONVERT(nvarchar(25),CheckInTimestamp, 121) + CONVERT(varchar(25), TicketId) = MaxKey
or CONVERT(nvarchar(25),CheckInTimestamp, 121) + CONVERT(varchar(25), TicketId) = MinKey
转换121是对数据时间重新分类的经典表达式如下:aaaa-mm-dd hh:mi:ss.mmm(24h),因此按字符串数据类型排序,它将给出与作为日期时间排序的结果相同的结果.
正如你可以看到这个连接不是很优化,任何想法?
更新我测试不同解决方案的方式:
我已经在SQL Server 2008 R2的真实数据库中测试了所有答案,并在3M行中选择了正确的表格.
如果我只获得第一个或最后一个访问过的人:
> Joe Taras的解决方案持续10秒.
> GarethD的解决方案持续21秒.
如果我通过分组列进行了同样的访问但是有一个有序的结果:
> Joe Taras的解决方案持续10秒.
> GarethD的解决方案持续46秒.
如果我同时获得有序结果的人(第一个和最后一个):
>乔塔拉斯(做联盟)解决方案持续19秒.
> GarethD的解决方案持续49秒.
其余的解决方案(甚至我的)在第一次测试中持续超过60秒,所以我取消了它.
最佳答案 试试这个:
select a.*
from AccessRecord a
where not exists(
select 'next'
from AccessRecord a2
where a2.movieid = a.movieid
and a2.theaterid = a.theaterid
and a2.showid = a.showid
and a2.checkintimestamp > a.checkintimestamp
)
通过这种方式,您可以选择最后一行作为同一部电影的时间戳,teather,show.
票据(我猜)每行都不同