Firstly, it must be said that using SQL's native table partitioning support is preferred. But that requires SQL Enterprise, which is a lot of money, so, presumably, here we are.
A few things for you to check:
- Partition column must be part of primary key
- Partition column must have one and only one
CHECK
constraint
- Partitions must not overlap. Perhaps you have a typo, or my eyes fail me, but your constraints on
sales_1
and sales_2
overlap.
- Make sure the constraints are checked (
WITH CHECK CHECK CONSTRAINT
). Given your definition in the question, it probably isn't the issue, but it is in general a necessary troubleshooting step (take a look at SELECT name, is_not_trusted FROM sys.check_constraints
)
EDIT
Apparently DATEPART
doesn't work. Probably you should just specify the dates directly (s_date >= '2014-01-01' AND s_date < '2014-06-01'
), etc. You could also use persisted custom columns.
See: https://stackoverflow.com/questions/11155758/partitioned-view-not-working
Some other things to note about partitioned views, most of which I ran into quickly:
IDENTITY
columns will prevent inserts. What I did to get around this was create a "staging" table with the same structure (and an identity column), and add a trigger that just inserts into the partitioned view and deletes from the staging table. At some point I will look into using SQL 2012's SEQUENCE
s
- You can't run an update/delete query on the PV if it has a self-join on the PV or any of its tables
- All columns have to be specified in an
INSERT
statement. DEFAULT
doesn't work or help. You can't omit nullable columns or columns with a default value.
- If you use replication, it tends to disable the constraints (
NOT FOR REPLICATION
), so you'll have to make sure that doesn't happen
You can see here at the bottom: http://technet.microsoft.com/en-us/library/aa933141(v=sql.80).aspx
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
You could use
WHERE NOT EXISTS
to achieve what you need:You can find more information here: EXISTS (Transact-SQL)