2017-08-08 3 views
0

Il y a une table définie comme:Comment voulez-vous récupérer efficacement la première série de positions pour la journée en cours compte tenu du tableau ci-dessus dans un grand ensemble de données

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) 
) 

Ce tableau tient les positions de compte des données qui sont ajoutés à Plusieurs fois par jour Il y a actuellement environ 24 millions de lignes dans le tableau. Chaque fois que nous ajoutons des positions supplémentaires, nous ajoutons environ 32 000 entrées à cette table, et toutes les 32 000 entrées auront le même load_id. Le load_id est incrémenté de un chaque fois que nous chargeons un lot de 32 000 entrées (c'est-à-dire que les premières 32K entrées ont load_id = 1, la prochaine 32K a load_id = 2, etc ...). Le champ datetime_stamp indique l'heure à laquelle les entrées ont été chargées et est la même pour toutes les entrées 32K dans un seul chargement.

Comment pourriez-vous récupérer efficacement le premier ensemble de positions pour le jour en cours, compte tenu de la définition du tableau ci-dessus?

Exemple: Aujourd'hui, les positions ont été chargées dans ce tableau à 8h, 10h et 15h. À 17 heures aujourd'hui, nous voulons savoir quelles positions ont été chargées à 8 heures du matin puisque c'est la première charge qui s'est produite aujourd'hui. Notez que pour un jour donné, il peut y avoir un nombre différent de charges et les moments où les charges se produisent peuvent varier.

+0

pouvez-vous ajouter quelques données d'échantillon. INSERTs éventuellement. – theDbGuy

+0

Étiquetez votre question avec la base de données que vous utilisez. –

Répondre

2

Voici une méthode:

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; 

Cette base de données est assez agnostique.

Dans SQL Server, vous trouverez peut-être que c'est le meilleur:

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

Un index sur positions(datetime) fonctionnera, mais peut-être plus pour la where que pour le order by.

0

Maintenant vous avez un champ d'horodatage, mais il n'y a pas d'index dessus et je suppose que vous êtes surtout intéressé par les données du dernier jour (deux jours). Dans ce cas, ce que vous pouvez vouloir avoir est un jour de positions (nouveau champ de type DATE) et construire l'index sur ce Positions Date et load_id. Vous pouvez ensuite interroger efficacement les enregistrements à partir de la date et de la charge par lots (intraday).

0

Vous avez une reduncandy dans votre table, car load_id détermine datetime_stamp. Pensez à conserver une table de chargement avec datetime_stamp et utilisez simplement load_id dans la table. Pour SQL Server, cela fonctionnera, pour les autres SGBDR modifier le travail de type de données. Je viens de couper l'heure de la date actuelle. Je PL/SQL cela peut être fait beaucoup plus joli

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)) 
)