如果在大型数据集中给出上表,您将如何有效地检索当天的第一组头寸

时间:2017-08-08 13:34:37

标签: sql data-retrieval

有一个表定义为:

CREATE TABLE[Positions](
            [load_id]           [int]                  NOT NULL, 
            [acct_cd]         [varchar](20)   NOT NULL,
            [acct_num]      [varchar](255)             NULL,
            [sec_id]            [varchar](50)   NOT NULL,
            [long_sht_cd]   [varchar](3)     NOT NULL,
            [sedol]              [varchar](15)   NULL,
            [isin]                 [varchar](15)   NULL,
            [cusip]              [varchar](9)     NULL,
            [sec_type]       [varchar](8)     NULL,
            [sec_name]     [varchar](100)NULL,
            [currency_cd] [varchar](3)     NULL,
            [total_holding] [decimal](18, 4)NULL,
            [mkt_price]      [float]               NULL,
            [datetime_stamp] [datetime]   NULL,
CONSTRAINT [pk_Positions] PRIMARY KEY CLUSTERED(       
[load_id] ASC, 
            [acct_cd] ASC, 
            [sec_id] ASC,
            [long_sht_cd] ASC )
)

此表包含每天多次附加的帐户头寸数据 目前表中有大约2400万行。每次我们追加其他职位时,我们都会在此表中添加大约32,000个条目,并且所有32,000个条目都具有相同的load_id。每次加载一批32,000个条目时,load_id都会加1(即前32K条目的load_id = 1,下一个32K的load_id = 2,等等......)。 datetime_stamp字段显示条目的加载时间,并且对于单个加载中的所有32K条目都是相同的。

在给定上述表定义的情况下,您如何有效地检索当天的第一组头寸?

实施例: 今天上午8点,上午10点和下午3点,这些职位被加载到这张桌子上。今天下午5点我们想知道早上8点装货的位置,因为那是今天发生的第一次装货。请注意,对于任何给定的日期,可能存在不同数量的负载,并且负载发生的时间会有所不同。

3 个答案:

答案 0 :(得分:2)

这是一种方法:

select p.*
from (select p.*, dense_rank() over (order by datetime) as seqnum
      from positions p
      where p.datetime >= @date and p.datetime < @date + interval '1 day'
    ) p
where seqnum = 1;

这与数据库无关。

在SQL Server中,您可能会发现这是最好的:

select top (1) with ties p.*
from positions p
where p.datetime >= @date and p.datetime < dateadd(day, 1, @date)
order by p.datetime;

positions(datetime)上的索引可行,但where可能比order by更多。

答案 1 :(得分:0)

现在你有了日期时间戳字段,但它没有索引,我假设你最感兴趣的是最后一天(两天)的数据。在这种情况下,您可能希望拥有的是职位日(新的DATE类型字段)和此Positions Dateload_id的构建索引。然后,您可以有效地查询特定日期和批量加载(日内)的记录。

答案 2 :(得分:0)

你的表中有一个reduncandy,因为load_id决定了datetime_stamp。考虑使用datetime_stamp保存一个load表,并使用表中的load_id。

对于SQL Server,这将有效,因为其他RDBMS会更改数据类型的工作。我只是缩短当前日期的时间。我PL / SQL这可以做得更漂亮

select *
from Positions
where datetime_stamp=(select min(datetime_stamp) from positions where datetime_stamp between 
cast(CAST(GETDATE() as date) as datetime2) and 
dateadd(MS,-1,cast(dateadd(day,1,CAST(GETDATE() as date)) as datetime2))
)