Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
mattlightbourn
Starting Member
37 Posts |
Posted - 2009-12-01 : 07:30:38
|
Dear all,I don't understand why I'm having a HAVING issue with this script. I need the where statements and I need to group the whole lot by the Company and FunctionalGroup.The result I'm after isCompany FunctionalGroup Last3Months Last6Months Prev3MonthsAVIVA Designers 1350 3600 1250AVIVA Production 850 1995 1145 What have I done that's wrong? ThanksSELECT FM_Timesheets.Studio_Company , FM_Timesheets.FunctionalGroup ,Last6Months.TimeEntryValue ,Last3Months.TimeEntryValue ,Prev3Months.TimeEntryValueFROM FM_TimesheetsLEFT OUTER JOIN (SELECT SUM (TimeEntry) as TimeEntryValue, Studio_Company, FunctionalGroup FROM FM_Timesheets WHERE TimeDate > MAX(TimeDate)-180) GROUP BY Studio_Company, FunctionalGroup) Last6MonthsON FM_Timesheets.Studio_Company = Last6Months.Studio_CompanyLEFT OUTER JOIN (SELECT SUM (TimeEntry) as TimeEntryValue, Studio_Company, FunctionalGroup FROM FM_Timesheets WHERE TimeDate > MAX(TimeDate)-90) GROUP BY Studio_Company, FunctionalGroup) Last3MonthsON FM_Timesheets.Studio_Company =Last3Months.Studio_CompanyLEFT OUTER JOIN (SELECT SUM (TimeEntry) as TimeEntryValue, Studio_Company, FunctionalGroup FROM FM_Timesheets WHERE TimeDate > MAX(TimeDate)-90) AND TimeDate < MAX(TimeDate)-180 GROUP BY Studio_Company, FunctionalGroup) Prev3MonthsON FM_Timesheets.Studio_Company = Prev3Months.Studio_Company GROUP BY FM_Timesheets.Studio_Company , FM_Timesheets.FunctionalGroup ORDER BY FM_Timesheets.Studio_Company , FM_Timesheets.FunctionalGroup |
|
|
mattlightbourn
Starting Member
37 Posts |
Posted - 2009-12-01 : 07:50:23
|
I've edited it, maybe this looks better but, it still doesn't work:SELECT FM_Timesheets.Studio_Company , FM_Timesheets.FunctionalGroup ,Last6Months.TimeEntryValue ,Last3Months.TimeEntryValue ,Prev3Months.TimeEntryValueFROM FM_TimesheetsLEFT OUTER JOIN (SELECT SUM (TimeEntry) as TimeEntryValue, Studio_Company, FunctionalGroup FROM FM_Timesheets WHERE TimeDate > MAX(TimeDate)-180)-- GROUP BY Studio_Company, FunctionalGroup) Last6MonthsON FM_Timesheets.Studio_Company = Last6Months.Studio_CompanyAND FM_Timesheets.FunctionalGroup = Last6Months.FunctionalGroupLEFT OUTER JOIN (SELECT SUM (TimeEntry) as TimeEntryValue, Studio_Company, FunctionalGroup FROM FM_Timesheets WHERE TimeDate > MAX(TimeDate)-90)-- GROUP BY Studio_Company, FunctionalGroup) Last3MonthsON FM_Timesheets.Studio_Company =Last3Months.Studio_CompanyAND FM_Timesheets.FunctionalGroup = Last3Months.FunctionalGroupLEFT OUTER JOIN (SELECT SUM (TimeEntry) as TimeEntryValue, Studio_Company, FunctionalGroup FROM FM_Timesheets WHERE TimeDate > MAX(TimeDate)-90 AND TimeDate < MAX(TimeDate)-180)-- GROUP BY Studio_Company, FunctionalGroup) Prev3MonthsON FM_Timesheets.Studio_Company = Prev3Months.Studio_CompanyAND FM_Timesheets.FunctionalGroup = Prev3Months.FunctionalGroup GROUP BY FM_Timesheets.Studio_Company , FM_Timesheets.FunctionalGroup ORDER BY FM_Timesheets.Studio_Company , FM_Timesheets.FunctionalGroup |
 |
|
|
jimf
Master Smack Fu Yak Hacker
2875 Posts |
Posted - 2009-12-01 : 08:01:30
|
You say you're having a HAVING issue, but I don't see any HAVING clauses in your script. Also, you can't do aggregates in a where clause, maybe that's where the HAVING clause would workFor example, instead ofSELECT SUM (TimeEntry) as TimeEntryValue, Studio_Company, FunctionalGroup FROM FM_Timesheets WHERE TimeDate > MAX(TimeDate)-90 AND TimeDate < MAX(TimeDate)-180)-- GROUP BY Studio_Company, FunctionalGroup useSELECT SUM (TimeEntry) as TimeEntryValue, Studio_Company, FunctionalGroup FROM FM_Timesheets GROUP BY Studio_Company, FunctionalGroupHAVING DATEDIFF (day,TimeDate,MAX(TimeDate))>90 JimEveryday I learn something that somebody else already knew |
 |
|
|
mattlightbourn
Starting Member
37 Posts |
Posted - 2009-12-01 : 08:05:21
|
| I'll give it a go, that sounds bang on - thank you |
 |
|
|
mattlightbourn
Starting Member
37 Posts |
Posted - 2009-12-01 : 08:16:13
|
I'm afriad that didn't work. I also forgot that I would like the report to be grouped my year and month as well so that the results do not come out as a record for every day that there was a timesheet.Here is my revised code:SELECT FM_Timesheets.Studio_Company , FM_Timesheets.FunctionalGroup , MONTH(FM_Timesheets.TimeDate) AS MonthNum , YEAR(FM_Timesheets.YearNum) AS YearNum ,Last6Months.TimeEntryValue ,Last3Months.TimeEntryValue ,Prev3Months.TimeEntryValueFROM FM_TimesheetsLEFT OUTER JOIN (SELECT SUM (TimeEntry) as TimeEntryValue, Studio_Company, FunctionalGroup, monthnum FROM FM_Timesheets GROUP BY YEAR(TimeDate), MONTH(TimeDate), Studio_Company, FunctionalGroup HAVING DATEDIFF (day,TimeDate,MAX(TimeDate))<180) Last6MonthsON FM_Timesheets.Studio_Company = Last6Months.Studio_CompanyAND FM_Timesheets.FunctionalGroup = Last6Months.FunctionalGroupLEFT OUTER JOIN (SELECT SUM (TimeEntry) as TimeEntryValue, Studio_Company, FunctionalGroup, monthnum FROM FM_Timesheets GROUP BY YEAR(TimeDate), MONTH(TimeDate), Studio_Company, FunctionalGroup HAVING DATEDIFF (day,TimeDate,MAX(TimeDate))<90) Last3MonthsON FM_Timesheets.Studio_Company =Last3Months.Studio_CompanyAND FM_Timesheets.FunctionalGroup = Last3Months.FunctionalGroupLEFT OUTER JOIN (SELECT SUM (TimeEntry) as TimeEntryValue, Studio_Company, FunctionalGroup, monthnum FROM FM_Timesheets GROUP BY YEAR(TimeDate), MONTH(TimeDate), Studio_Company, FunctionalGroup HAVING DATEDIFF (day,TimeDate,MAX(TimeDate))<90 AND DATEDIFF (day,TimeDate,MAX(TimeDate))<180) Prev3MonthsON FM_Timesheets.Studio_Company = Prev3Months.Studio_CompanyAND FM_Timesheets.FunctionalGroup = Prev3Months.FunctionalGroup GROUP BY FM_Timesheets.Studio_Company , FM_Timesheets.FunctionalGroup , YEAR(TimeDate), MONTH(TimeDate) ORDER BY FM_Timesheets.Studio_Company , FM_Timesheets.FunctionalGroup The error I now get is:Msg 8121, Level 16, State 1, Line 1Column 'FM_Timesheets.TimeDate' is invalid in the HAVING clause because it is not contained in either an aggregate function or the GROUP BY clause.It's infuriating - thank you again for your helpKind Regards Matt |
 |
|
|
mattlightbourn
Starting Member
37 Posts |
Posted - 2009-12-01 : 08:30:54
|
I'm getting the error even when I have made it into one part of the issue - I've never had this problem before, grrrhMsg 8121, Level 16, State 1, Line 1Column 'FM_Timesheets.TimeDate' is invalid in the HAVING clause because it is not contained in either an aggregate function or the GROUP BY clause.SELECT Year(TimeDate) , Month(TimeDate) , Studio_Company , FunctionalGroup , SUM(TimeEntry) AS SumHoursFROM FM_TimesheetsGROUP BY Studio_Company, FunctionalGroup, Year(TimeDate), Month(TimeDate)HAVING DATEDIFF(Day, TimeDate, MAX(TimeDate))>90 |
 |
|
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2009-12-01 : 08:33:44
|
Hi.First off, here's your query with some slightly better formatting.SELECT FM_Timesheets.Studio_Company , FM_Timesheets.FunctionalGroup , MONTH(FM_Timesheets.TimeDate) AS MonthNum , YEAR(FM_Timesheets.YearNum) AS YearNum ,Last6Months.TimeEntryValue ,Last3Months.TimeEntryValue ,Prev3Months.TimeEntryValueFROM FM_Timesheets LEFT OUTER JOIN ( SELECT SUM (TimeEntry) as TimeEntryValue , Studio_Company , FunctionalGroup , monthnum FROM FM_Timesheets GROUP BY YEAR(TimeDate) , MONTH(TimeDate) , Studio_Company , FunctionalGroup HAVING DATEDIFF (day, TimeDate , MAX(TimeDate) ) < 180 ) Last6Months ON FM_Timesheets.Studio_Company = Last6Months.Studio_Company AND FM_Timesheets.FunctionalGroup = Last6Months.FunctionalGroup LEFT OUTER JOIN ( SELECT SUM (TimeEntry) as TimeEntryValue , Studio_Company , FunctionalGroup , monthnum FROM FM_Timesheets GROUP BY YEAR(TimeDate) , MONTH(TimeDate) , Studio_Company , FunctionalGroup HAVING DATEDIFF (day,TimeDate,MAX(TimeDate) ) < 90 ) Last3Months ON FM_Timesheets.Studio_Company =Last3Months.Studio_Company AND FM_Timesheets.FunctionalGroup = Last3Months.FunctionalGroup LEFT OUTER JOIN ( SELECT SUM (TimeEntry) as TimeEntryValue , Studio_Company , FunctionalGroup , monthnum FROM FM_Timesheets GROUP BY YEAR(TimeDate) , MONTH(TimeDate) , Studio_Company , FunctionalGroup HAVING DATEDIFF ( day,TimeDate,MAX(TimeDate) ) < 90 AND DATEDIFF ( day,TimeDate,MAX(TimeDate) ) < 180 ) Prev3Months ON FM_Timesheets.Studio_Company = Prev3Months.Studio_Company AND FM_Timesheets.FunctionalGroup = Prev3Months.FunctionalGroupGROUP BY FM_Timesheets.Studio_Company , FM_Timesheets.FunctionalGroup , YEAR(TimeDate), MONTH(TimeDate)ORDER BY FM_Timesheets.Studio_Company , FM_Timesheets.FunctionalGroup The problem is in your left joins.You can debug it by just trying to get this part working:SELECT SUM (TimeEntry) as TimeEntryValue , Studio_Company , FunctionalGroup , monthnum FROM FM_Timesheets GROUP BY YEAR(TimeDate) , MONTH(TimeDate) , Studio_Company , FunctionalGroup HAVING DATEDIFF (day, TimeDate , MAX(TimeDate) ) < 180 Now maybe you should try and explain what you want to accomplish. The technical reason the error is thrown is because timedate is not in the group by clause YEAR(timedate) and MONTH(timedate) are but that's no enough.Maybe if you gave some sample data and expected output (just for this chunk of code) we can suggest something (probably a better way).I think that this could be rewritten completely without resorting to YEAR and MONTH and without using 3 different left joins.Fell free to just start at the start and post sample data for the relevant tables and desired results. I think you've got stuck in the trap of just writing MORE sql to try and get what you want.Regards,Charlie===============================================================Msg 3903, Level 16, State 1, Line 1736The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION |
 |
|
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2009-12-01 : 08:46:27
|
Maybe ditch the having clauses altogether.Does this work for you:DECLARE @referenceDate DATETIMEDECLARE @sixMonthsAgo DATETIME-- ReferenceDate is as of right now -- but this could be any time specifiedSET @referenceDate = GETDATE()-- set sixMonthsAgo = to the startof the day 6 months before the reference dateSET @sixMonthsAgo = DATEADD(DAY, 0, DATEDIFF(DAY, 0, DATEADD(MONTH, -6, @referenceDate)))SELECT @referenceDateSELECT @sixMonthsAgo-- Now we can ditch the HAVING clause and still use any INDEX on the timeDate columnSELECT SUM (TimeEntry) as TimeEntryValue , Studio_Company , FunctionalGroup , monthnumFROM FM_TimesheetsWHERE timeDate >= @sixMonthsAgo AND timeDate < @referenceDateGROUP BY YEAR(TimeDate) , MONTH(TimeDate) , Studio_Company , FunctionalGroup Charlie===============================================================Msg 3903, Level 16, State 1, Line 1736The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION |
 |
|
|
mattlightbourn
Starting Member
37 Posts |
Posted - 2009-12-01 : 08:52:35
|
Thank you for your reply.I have a table called FM_Timesheets with individual timesheet entries on there for different dates.Each timesheet has a user, who is a part of a FunctionalGroup and the users work at any one of the studios, so there is also Studio_Company.What I want to do is create a data source for a 'bubble chart' for a dashboard.It requires the following:Studio_Company, The average of TimeEntry from the last 3 months, The average of the TimeEntry from the PREVIOUS 3 months to that.To get the last three months of data I can do this:SELECT Year(TimeDate) AS YearNum , Month(TimeDate) AS MonthNum , Studio_Company , FunctionalGroup , SUM(TimeEntry)/3 AS SumHoursFROM FM_TimesheetsWHERE timedate > '2009-08-01'GROUP BY Studio_Company, FunctionalGroup, Year(TimeDate), Month(TimeDate) But I want the WHERE to look at what month we're in NOW - I guess done by GetDate() - minus 3 months, which would give me the manually entered above.To get the previous 3 months average:SELECT Year(TimeDate) AS YearNum , Month(TimeDate) AS MonthNum , Studio_Company , FunctionalGroup , SUM(TimeEntry)/3 AS SumHoursFROM FM_TimesheetsWHERE timedate > '2009-05-01' ANDWHERE timedate < '2009-08-01'GROUP BY Studio_Company, FunctionalGroup, Year(TimeDate), Month(TimeDate) What I want as my end result is:YearNum Studio_Company FunctionalGroup AVGLast AVGPrev2009 Chevron Design Production 37.166666 41.5543212009 Chevron Job Management 287.500000 255.6094552009 Chevron Digital Media 23.083333 20.4095502009 Chevron Creative 26.666666 27.584875 This can be in its own table created once a month then referenced by the chart I need to get into SharePointless, I mean, sharepoint.I hope this helps. Thank you for your supportMatt |
 |
|
|
mattlightbourn
Starting Member
37 Posts |
Posted - 2009-12-01 : 08:54:17
|
| Sorry Charlie, just noticed your other reply. I'm checking that nowthanks |
 |
|
|
mattlightbourn
Starting Member
37 Posts |
Posted - 2009-12-01 : 08:58:37
|
| Yeah, I think it does work! Mind you, how easy is it to get two ranges in there on the same rows? I take it I need a sub query within a query? |
 |
|
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2009-12-01 : 09:03:24
|
No -- I don't think so just repeat the whole process with another variable. Something like:DECLARE @referenceDate DATETIMEDEClARE @threeMonthsAgo DATETIMEDECLARE @sixMonthsAgo DATETIME-- ReferenceDate is as of right now -- but this could be any time specifiedSET @referenceDate = GETDATE()-- Set threeMonthsAgoSET @threeMonthsAgo = DATEADD(DAY, 0, DATEDIFF(DAY, 0, DATEADD(MONTH, -3, @referenceDate)))-- set sixMonthsAgo = to the startof the day 6 months before the reference dateSET @sixMonthsAgo = DATEADD(DAY, 0, DATEDIFF(DAY, 0, DATEADD(MONTH, -6, @referenceDate)))SELECT @referenceDateSELECT @threeMonthsAgoSELECT @sixMonthsAgo-- Now we can ditch the HAVING clause and still use any INDEX on the timeDate column-- Now to three months agoSELECT SUM (TimeEntry) as TimeEntryValue , Studio_Company , FunctionalGroup , monthnumFROM FM_TimesheetsWHERE timeDate >= @threeMonthsAgo AND timeDate < @referenceDateGROUP BY YEAR(TimeDate) , MONTH(TimeDate) , Studio_Company , FunctionalGroup-- The three months prior to thatSELECT SUM (TimeEntry) as TimeEntryValue , Studio_Company , FunctionalGroup , monthnumFROM FM_TimesheetsWHERE timeDate >= @sixMonthsAgo AND timeDate < @threeMonthsAgoGROUP BY YEAR(TimeDate) , MONTH(TimeDate) , Studio_Company , FunctionalGroup And then do each of those selects as a LEFT JOIN on whatever is appropriate.Charlie===============================================================Msg 3903, Level 16, State 1, Line 1736The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION |
 |
|
|
mattlightbourn
Starting Member
37 Posts |
Posted - 2009-12-01 : 09:05:33
|
| thank you very much, you're a star!! |
 |
|
|
|
|
|
|
|