December 18, 2003 at 1:43 pm
SELECT '01' as the_month,'2003' as the_year, isnull((SELECT SUM(num_units) from active_units_static where month_end = '1/31/2003'),0) + count(termnum) as active_units from active_Units where on_contract <= '1/31/2003' and (off_contract >= '1/31/2003' OR off_contract is null) UNION
SELECT '01','2002', isnull((SELECT SUM(num_units) from active_units_static where month_end = '1/31/2002'),0) + count(termnum) as active_units from active_Units where on_contract <= '1/31/2002' and (off_contract >= '1/31/2002' OR off_contract is null) UNION
SELECT '01','2001', isnull((SELECT SUM(num_units) from active_units_static where month_end = '1/31/2001'),0) + count(termnum) as active_units from active_Units where on_contract <= '1/31/2001' and (off_contract >= '1/31/2001' OR off_contract is null) UNION
SELECT '01','2000', isnull((SELECT SUM(num_units) from active_units_static where month_end = '1/31/2000'),0) + count(termnum) as active_units from active_Units where on_contract <= '1/31/2000' and (off_contract >= '1/31/2000' OR off_contract is null) UNION
SELECT '02','2003', isnull((SELECT SUM(num_units) from active_units_static where month_end = '2/28/2003'),0) + count(termnum) as active_units from active_Units where on_contract <= '2/28/2003' and (off_contract >= '2/28/2003' OR off_contract is null) UNION
etc for all 12 months and the 4 years you see up above. This select is quite long and I was trying to somehow shorten it, if its possible.
I have been trying myself to come up with a select that would accomplish this not using so many lines of code but not having much sucess.
SELECT '01' as the_month,year(on_contract) as the_year, isnull((SELECT SUM(num_units) from active_units_static where month_end = '1/31/2000'),0) + count(termnum) as active_units from active_units where on_contract <= '1/31/2000' and (off_contract> = '1/31/2000' OR off_contract is null) group by year(on_contract),month(on_contract)
this is how I started to try to simplify it but obviously it does not work. I am still unclear how just to get >= 2000 data but as it stands I am not even getting the corrent number of active_units.
So if anyone wants a challenge, fill free to offer suggestions.
FYI...on_contract,off_contract, and month_end are all datetime fields.
Matt
December 18, 2003 at 2:04 pm
How about something with case? Such as
Select the_month =
case
when convert(char(12), on_contract, 101) = '1/31/2003' then '01'
...
end
I realize that you have date ranges, so you'll have to parse out the month and year. I don't know how much shorter the query will be, but it might run faster.
December 18, 2003 at 2:14 pm
Thanks for the idea, but it wont be any any faster, if anything it will be slower since there is more processing as the month and year are both static currently and I don't see how your method would reduce the amount code, it looks like it would be more code with all the case statements I would need.
I do understand there will be more processing overhead, if I make it more dynamic but the case statements dont seem to be what I am looking for.
Matt
Edited by - matt101 on 12/18/2003 2:15:10 PM
December 18, 2003 at 2:25 pm
Select DatePart(m, EndOfMonthDate) as the_month,
DatePart(yyyy, EndOfMonthDate) as the_year,
isnull( (SELECT SUM(num_units) from active_units_static where month_end = EndOfMonthDate), 0)
+ count(termnum) as active_units
from active_Units
where on_contract <= EndOfMonthDate
and IsNULL(off_contract, EndOfMonthDate) >= EndOfMonthDate
Join
-- Select * From
(
Select Convert(DateTime, Convert(Varchar(8), DateAdd(m, 1-AMonth, DateAdd(yy, -ManyYears, GetDate())), 1)) - DatePart(d, GetDate())
As EndOfMonthDate
From (
Select Number as AMonth
From Master.dbo.spt_Values
Where Type = 'P' and Number Between 1 and 12) Months
Cross Join (
Select Number as ManyYears
From Master.dbo.spt_Values
Where Type = 'P' and Number Between 1 and 50) ManyYears -- may adjust the 5 to go back further
) EOMDates
Where EndOfMonthDate Between '1/31/2000' and '11/30/03' -- adjust WHERE to suit date needs
/*
The EOMDates derived table and WHERE clause can be run on there own to get a quick list of "last day of month" dates.
GHo ahead an run the derived table query by itself... from the "-- Select * From " line, just highlight "Select * From ..." to the end.
I went ahead an did the JOIN, but I'd rather see you rework the query to JOIN the active_units_static table.
Hope this helps.
*/
Once you understand the BITs, all the pieces come together
December 18, 2003 at 2:40 pm
I thought case might be faster despite the processor overhead if it could reduce the io.
December 19, 2003 at 7:56 am
I reworked the join, though I think you meant the active_units table and not the active_units_static, I almost got it 100% sytaxally working with one error saying
Line 18: Incorrect syntax near 'EOMDates'
I am not seeing anything wrong near line 18 which is right after the cross join. I do believe there are a few ) missing but I add them and still get the same error so I just removed them and the derived table did work so I am not 100% following where the incorrect syntax lies.
Below is the reworked query:
Select DatePart(m, EndOfMonthDate) as the_month,
DatePart(yyyy, EndOfMonthDate) as the_year,
isnull( (SELECT SUM(num_units) from active_units_static where month_end = EndOfMonthDate), 0) + count(termnum) as active_units from active_Units
Join EOMDates On the_month = Month(EndofMonthDate) AND the_year = year(EndofMonthDate)
-- Select * From
(
Select Convert(DateTime, Convert(Varchar(8), DateAdd(m, 1-AMonth, DateAdd(yy, - ManyYears, GetDate())), 1)) - DatePart(d, GetDate())
As EndOfMonthDate
From (
Select Number as AMonth
From Master.dbo.spt_Values
Where Type = 'P' and Number Between 1 and 12) Months
Cross Join (
Select Number as ManyYears
From Master.dbo.spt_Values
Where Type = 'P' and Number Between 1 and 50) ManyYears -- may adjust the 5 to go back further
) EOMDates
Where EndOfMonthDate Between '1/31/2000' and '12/31/03' -- adjust WHERE to suit date needs
where on_contract <= EndOfMonthDate and IsNULL(off_contract, EndOfMonthDate) >= EndOfMonthDate
Matt
P.S. If someone knows how to actually format the code so its more readable, let me know how to do it.
December 19, 2003 at 8:06 am
Matt, 1st thing I see is you have "WHERE" twice in one WHERE CLAUSE....
"where on_contract <="
should be
"and on_contract <="
As far a formatting the post, I use the "#" tool on the "post edit toolbar". This is {CODE} insert block. It also seems to be much better if I put an added [space] at the end of each line??.
Once you understand the BITs, all the pieces come together
December 19, 2003 at 8:24 am
Ahh I thought the first where statement was for the subquery and the 2nd where was for my original select, so I joined the 2 where's together and I am getting the same error message. ALso made a change to how I joined the tables together slightly. I also tried moving the On portion of the join after the subquery where i was getting my error at and that produced an Internal SQL Server error so I figured where I had it was correct. Below is my updated code.
Select DatePart(m, EndOfMonthDate) as the_month,
DatePart(yyyy, EndOfMonthDate) as the_year,
isnull( (SELECT SUM(num_units) from active_units_static where month_end = EndOfMonthDate), 0) + count(termnum) as active_units from active_Units
Join EOMDates ON DatePart(m, EndOfMonthDate) = month(EndofMonthDate) AND DatePart(yyyy, EndOfMonthDate) = year(EndofMonthDate)
-- Select * From
(
Select Convert(DateTime, Convert(Varchar(8), DateAdd(m, 1-AMonth, DateAdd(yy, - ManyYears, GetDate())), 1)) - DatePart(d, GetDate())
As EndOfMonthDate
From (
Select Number as AMonth
From Master.dbo.spt_Values
Where Type = 'P' and Number Between 1 and 12) Months
Cross Join (
Select Number as ManyYears
From Master.dbo.spt_Values
Where Type = 'P' and Number Between 1 and 50) ManyYears -- may adjust the 5 to go back further
) EOMDates
Where EndOfMonthDate Between '1/31/2000' and '12/31/03' AND on_contract <= EndOfMonthDate and IsNULL(off_contract, EndOfMonthDate) >= EndOfMonthDate
Thanks for all your help so far,
Matt
December 19, 2003 at 8:38 am
Sorry Matt, I had the WHERE above the JOIN in my initial post... anyway, let's splitup the complexity...
-- Make EOMDates table
If Object_ID('TempDB..#EOMDates') id Not NULL Drop Table #EOMDates
Select * Into #Temp From
(
Select Convert(DateTime, Convert(Varchar(8), DateAdd(m, 1-AMonth, DateAdd(yy, -ManyYears, GetDate())), 1)) - DatePart(d, GetDate())
As EndOfMonthDate
From (
Select Number as AMonth
From Master.dbo.spt_Values
Where Type = 'P' and Number Between 1 and 12) Months
Cross Join (
Select Number as ManyYears
From Master.dbo.spt_Values
Where Type = 'P' and Number Between 1 and 50) ManyYears -- may adjust the 5 to go back further
) EOMDates
Where EndOfMonthDate Between '1/31/2000' and '11/30/03' -- adjust WHERE to suit date needs
-- Now Simplified SELECT
Select DatePart(m, EndOfMonthDate) as the_month,
DatePart(yyyy, EndOfMonthDate) as the_year,
isnull( (SELECT SUM(num_units) from active_units_static where month_end = EndOfMonthDate), 0)
+ count(termnum) as active_units
from active_Units
Join EOMDates
On on_contract <= EndOfMonthDate
and IsNULL(off_contract, EndOfMonthDate) >= EndOfMonthDate
Let me know.
Once you understand the BITs, all the pieces come together
December 19, 2003 at 8:40 am
Let's try again...
-- Make #EOMDates table
If Object_ID('TempDB..#EOMDates') id Not NULL Drop Table #EOMDates
Select * Into #EOMDates From
(
Select Convert(DateTime, Convert(Varchar(8), DateAdd(m, 1-AMonth, DateAdd(yy, -ManyYears, GetDate())), 1)) - DatePart(d, GetDate())
As EndOfMonthDate
From (
Select Number as AMonth
From Master.dbo.spt_Values
Where Type = 'P' and Number Between 1 and 12) Months
Cross Join (
Select Number as ManyYears
From Master.dbo.spt_Values
Where Type = 'P' and Number Between 1 and 50) ManyYears -- may adjust the 5 to go back further
) EOMDates
Where EndOfMonthDate Between '1/31/2000' and '11/30/03' -- adjust WHERE to suit date needs
-- Now Simplified SELECT
Select DatePart(m, EndOfMonthDate) as the_month,
DatePart(yyyy, EndOfMonthDate) as the_year,
isnull( (SELECT SUM(num_units) from active_units_static where month_end = EndOfMonthDate), 0)
+ count(termnum) as active_units
from active_Units
Join EOMDates
On on_contract <= EndOfMonthDate
and IsNULL(off_contract, EndOfMonthDate) >= EndOfMonthDate
Once you understand the BITs, all the pieces come together
December 19, 2003 at 8:42 am
It's getting close to vacation time 🙂 so my typing is getting rough :(.... last post I had "is" misplelled as "id". Please correct... It's hard to test some of these things when you don't have the core source tables.
I'll stick with you though.
Once you understand the BITs, all the pieces come together
December 19, 2003 at 9:02 am
Yes I noticed that, but I figured that out without your help. :]
ALso your temp tables where messed up as well. Yes, you need a vacation. That gets me my data and got the right # of active_units.
Only issue I see now, is I am only getting up to 2002 data no 2003 data but I think I can fix that one.
Also thinking about making that a regular table and not a temp table as i have other selects that will be following what we just did.
Enjoy your vacation and thanks for all your help,
MAtt
December 19, 2003 at 9:39 am
Matt, I apologize again for the errors .
Thanks for your patience.
I hope I at least provided some things to help you and maybe others.
Vacation is indeed long over due. It's to the point of "use it or lose it", which means I really need it. Hope I don't spend the entire vacation in bed trying to get over this cold/flu bug I have.
I'll be araoung 'til ~2PM EST today, then back on the 29th. Happy Holidays
Once you understand the BITs, all the pieces come together
Viewing 13 posts - 1 through 12 (of 12 total)
You must be logged in to reply to this topic. Login to reply