Technically to display n-th value you use the ranking functions like RANK
, DENSE_RANK
or ROW_NUMBER
. Which one exactly depends, but what you describe matches best ROW_NUMBER
:
with cte as (
select row_number() over (order by Date) as rn, *
from table)
where rn % 1000 = 0;
But you are saying that you want o do this for performance reasons, avoid going through millions of rows. Such a query had already done the damage, it read from disk all the rows and had to sort them so the performance price was already payed.
A better alternative to selecting a random sample of data is to use the TABLESAMPLE
clause, see Limiting Result Sets by Using TABLESAMPLE:
select *
from table tablesample (100 rows);
TABLESAMPLE will be way more efficient as it actually avoids reading all the data, it only samples some of the pages in the table and returns all rows in the sampled pages.
But consider that if you use TABLESAMPLE your WHERE clause are applied after the sampling. So it may be that the sample does not contain any row for the device/sensor you're interested in. This is specially true for sensor with small data.
Expanding on James' answer
Try this code on SqlFiddle.
Also check out @SqlKiwi Paul White's post regarding Delete vs Truncate
create table tracker_live (
client_nbr int not null, tracker_date date not null, submit_date date not null, live float not null, retainer float not null, bonus float not null
, constraint pk_tracker_live primary key (client_nbr, tracker_date, submit_date));
insert into tracker_live (client_nbr, tracker_date, submit_date, live, retainer, bonus) values
(9,'2014-10-01','2014-10-08',537841.5657,1,1)
,(9,'2014-11-01','2014-10-08',890293.714,2,2)
,(9,'2014-12-01','2014-10-08',45585.4029,3,3)
,(9,'2014-10-01','2014-10-17',537841.5657,1,1)
,(9,'2014-11-01','2014-10-17',890293.714,2,2)
,(9,'2014-12-01','2014-10-17',45585.4029,3,3)
,(9,'2014-10-01','2014-11-13',2321938.59,1,1)
,(9,'2014-11-01','2014-11-13',907925.1072,2,2)
,(9,'2014-12-01','2014-11-13',392917.5237,3,3)
,(9,'2014-10-01','2014-11-18',2321938.59,1,1)
,(9,'2014-11-01','2014-11-18',795725.1072,2,2)
,(9,'2014-12-01','2014-11-18',725835.0474,3,3)
create table tracker_live_last_month (
client_nbr int not null, tracker_date date not null, submit_date date not null, live float not null, retainer float not null, bonus float not null
, constraint pk_tracker_live_last_month primary key (client_nbr, tracker_date));
/* example query for procedure */
declare @test date;
set @test = '2014-11-18';
--set @test = convert(date,getdate());
declare @LastDayOfLastMonth date;
set @LastDayOfLastMonth = dateadd(day,-datepart(day,@test),@test);
declare @FirstDayOfLastMonth date;
set @FirstDayOfLastMonth = dateadd(day,1-datepart(day,@LastDayOfLastMonth),@LastDayOfLastMonth);
truncate table tracker_live_last_month;
/* inserting the data with this combined query should be quicker than creating the table and then updating values */
insert into tracker_live_last_month (client_nbr, tracker_date, submit_date, live, retainer, bonus)
select tl.client_nbr, tl.tracker_date, ca.submit_date, ca.live, ca.retainer, ca.bonus
from tracker_live tl
cross apply (select top 1 i.submit_date, i.live, i.retainer, i.bonus
from tracker_live i
where i.client_nbr=tl.client_nbr
and i.tracker_date=tl.tracker_date
order by i.submit_date desc) as ca
where tl.submit_date between @FirstDayOfLastMonth and @LastDayofLastMonth
group by tl.client_nbr, tl.tracker_date, ca.submit_date, ca.retainer, ca.live, ca.bonus
order by tl.client_nbr, tl.tracker_date, ca.submit_date, ca.retainer, ca.live, ca.bonus;
Best Answer
For recent versions of SQL-Server that support CTEs (and not the obsolete 2000):
Using a CTE and copying a trick of @Paul White in this answer (to get
TOP
in the recursive part of the CTE): How to recursively find gaps where 90 days passed, between rowsA cursor solution, that works in older versions (I don't have a 2000 instance to test and the following will probably need adjustments). Modified from another answer, in the same question How to recursively find gaps where 90 days passed, between rows:
(first, some needed tables and variables):
The actual cursor:
And getting the results:
Tested at SQLfiddle (in 2008 version).