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 |
|
musclebreast
Yak Posting Veteran
77 Posts |
Posted - 2012-07-01 : 08:49:32
|
Hello,I hope you can help me.I've got one Table with the following columns:ID.........ATTRID......Valdate.......ValStr....ValINT1234........4...........2012/8/8......Null......NULL1234........7..........Null............5........NULL1234........10.........NULL...........NULL.......dayI need to filte it in one Row (ID is the same):ID....Valdate.....Valstr....ValINT1234...2012/8/8.....5.........dayI tried it as followed:SELECTID,CASE WHEN AttrID = '4' THEN Valdate END as Valdate, Case WHEN AttrID = '7' THEN ValInt END as Valstr, Case WHEN AttrID = '10' THEN ValStr END as Valint FROM dbo.llattrdata A1Group BY ID I get the following error:Column 'dbo.llattrdata.AttrID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.How can I solve the problem?Kind regards,Lara |
|
|
sunitabeck
Master Smack Fu Yak Hacker
5155 Posts |
Posted - 2012-07-01 : 10:31:57
|
Change it to this:SELECT ID, CASE WHEN AttrID = '4' THEN MAX(Valdate) END AS Valdate, CASE WHEN AttrID = '7' THEN MAX(ValInt) END AS Valstr, CASE WHEN AttrID = '10' THEN MAX(ValStr) END AS ValintFROM dbo.llattrdata A1GROUP BY ID If your sample data is really representative of your actual data - i.e., all the rows except one are nulls for each of the columns of interest, you could even do this:SELECT ID, MAX(Valdate) AS Valdate, MAX(ValInt) AS Valstr, MAX(ValStr) AS ValintFROM dbo.llattrdata A1GROUP BY ID |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-07-01 : 11:27:17
|
quote: Originally posted by musclebreast Hello,I hope you can help me.I've got one Table with the following columns:ID.........ATTRID......Valdate.......ValStr....ValINT1234........4...........2012/8/8......Null......NULL1234........7..........Null............5........NULL1234........10.........NULL...........NULL.......dayI need to filte it in one Row (ID is the same):ID....Valdate.....Valstr....ValINT1234...2012/8/8.....5.........dayI tried it as followed:SELECTID,CASE WHEN AttrID = '4' THEN Valdate END as Valdate, Case WHEN AttrID = '7' THEN ValInt END as Valstr, Case WHEN AttrID = '10' THEN ValStr END as Valint FROM dbo.llattrdata A1Group BY ID I get the following error:Column 'dbo.llattrdata.AttrID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.How can I solve the problem?Kind regards,Lara
can there be more than one record with same ATTRID for an ID value?------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
duf
Starting Member
39 Posts |
Posted - 2012-07-01 : 11:43:16
|
quote: Originally posted by sunitabeck Change it to this:SELECT ID, CASE WHEN AttrID = '4' THEN MAX(Valdate) END AS Valdate, CASE WHEN AttrID = '7' THEN MAX(ValInt) END AS Valstr, CASE WHEN AttrID = '10' THEN MAX(ValStr) END AS ValintFROM dbo.llattrdata A1GROUP BY ID If your sample data is really representative of your actual data - i.e., all the rows except one are nulls for each of the columns of interest, you could even do this:SELECT ID, MAX(Valdate) AS Valdate, MAX(ValInt) AS Valstr, MAX(ValStr) AS ValintFROM dbo.llattrdata A1GROUP BY ID
I have one question. If the query begins with the word SELECT result is the only answer. How will this convert 3 rows to one? |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-07-01 : 11:46:17
|
| see the group by. it groups rows based on id value. and max() will ensure you get non null value for each attribute------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
musclebreast
Yak Posting Veteran
77 Posts |
Posted - 2012-07-01 : 17:18:05
|
Hi,thanks. I learned something:)Your second solutions works:SELECT ID, MAX(Valdate) AS Valdate, MAX(ValInt) AS Valstr, MAX(ValStr) AS ValintFROM dbo.llattrdata A1GROUP BY ID But not the first one and I don't get because it's the same statement except the CASE WHEN AttrID = '4' term. It seems here is the problem. I get the following error:Column 'dbo.llattrdata.AttrID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.What might be the problem here?I really need to know it, because I need the when-statement. The reason is that the column Valint has two Values in two rows which I can filter through the AttrID. Take a look at the Table:ID.........ATTRID......Valdate.......ValStr....ValINT1234........4...........2012/8/8......Null......NULL1234........7..........Null............5........NULL1234........10.........NULL...........NULL.......day1234........11.........NULL..........NULL........end of quarterI need to filter it in one Row (ID is the same):ID....Valdate.....Valstr....ValINT....ValInt11234...2012/8/8.....5.........day......end of quarterKind regards,Lara |
 |
|
|
bitsmed
Aged Yak Warrior
545 Posts |
Posted - 2012-07-01 : 18:25:47
|
Seems like you choose wrong field in case statement, when comparing attrid=7 and attrid=10. Shouldn't those two be switched? (when attrid=7 then return valstr, when attrid=10 then return valint)Anyway, here's my suggestion:select id ,max(case when attrid='4' then valdate else null end ) as valdate ,max(case when attrid='7' then valstr else null end ) as valstr ,max(case when attrid='10' then valint else null end ) as valint ,max(case when attrid='11' then valint else null end ) as valint1 from dbo.llattrdata group by id |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-07-01 : 19:02:17
|
quote: Originally posted by musclebreast Hi,thanks. I learned something:)Your second solutions works:SELECT ID, MAX(Valdate) AS Valdate, MAX(ValInt) AS Valstr, MAX(ValStr) AS ValintFROM dbo.llattrdata A1GROUP BY ID But not the first one and I don't get because it's the same statement except the CASE WHEN AttrID = '4' term. It seems here is the problem. I get the following error:Column 'dbo.llattrdata.AttrID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.What might be the problem here?I really need to know it, because I need the when-statement. The reason is that the column Valint has two Values in two rows which I can filter through the AttrID. Take a look at the Table:ID.........ATTRID......Valdate.......ValStr....ValINT1234........4...........2012/8/8......Null......NULL1234........7..........Null............5........NULL1234........10.........NULL...........NULL.......day1234........11.........NULL..........NULL........end of quarterI need to filter it in one Row (ID is the same):ID....Valdate.....Valstr....ValINT....ValInt11234...2012/8/8.....5.........day......end of quarterKind regards,Lara
once you've GROUP BY you cant directly reference fields.------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
musclebreast
Yak Posting Veteran
77 Posts |
Posted - 2012-07-02 : 05:33:49
|
| Hello,Thanks bitsmed for your suggestion, but unfortunately it doesn't work. I get the following error:Msg 102, Level 15, State 1, Line 5Incorrect syntax near '='.@visakh16: Sorry for asking again, but did I understand it right, that I can't use my problem with a sql statement?Kind regards,Lara |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-07-02 : 19:15:03
|
probably this is what you're afterSELECTID,MAX(CASE WHEN AttrID = '4' THEN Valdate END) as Valdate, MAX(Case WHEN AttrID = '7' THEN ValInt END) as Valstr, MAX(Case WHEN AttrID = '10' THEN ValStr END) as Valint FROM dbo.llattrdata A1Group BY ID ------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
musclebreast
Yak Posting Veteran
77 Posts |
Posted - 2012-07-14 : 16:18:57
|
| Hi Visakh16,yes your last solutions works, but it'S not excact what I was asking. Look..that's my problem:SELECTID,MAX(CASE WHEN AttrID = '5' THEN Valdate END) as Valdate, MAX(Case WHEN AttrID = '7' THEN ValInt END) as Valstr, MAX(Case WHEN AttrID = '10' THEN ValStr END) as Valint MAX(Case WHEN AttrID = '11' THEN ValStr END) as Valint1FROM dbo.llattrdata A1Where ID = '434473'Group BY IDHere is the problem:MAX(Case WHEN AttrID = '10' THEN ValStr END) as Valint MAX(Case WHEN AttrID = '11' THEN ValStr END) as Valint1I'got two different rows, but the same column...I get the following error:Msg 102, Level 15, State 1, Line 10Incorrect syntax near 'MAX'.Can I go another way? Is mas still the right function?Kind regards,Lara |
 |
|
|
bitsmed
Aged Yak Warrior
545 Posts |
Posted - 2012-07-14 : 17:15:45
|
quote: Here is the problem:MAX(Case WHEN AttrID = '10' THEN ValStr END) as Valint MAX(Case WHEN AttrID = '11' THEN ValStr END) as Valint1I'got two different rows, but the same column...I get the following error:Msg 102, Level 15, State 1, Line 10Incorrect syntax near 'MAX'.
You need a comma to seperate here fields:MAX(Case WHEN AttrID = '10' THEN ValStr END) as Valint,MAX(Case WHEN AttrID = '11' THEN ValStr END) as Valint1 |
 |
|
|
musclebreast
Yak Posting Veteran
77 Posts |
Posted - 2012-07-14 : 17:51:24
|
| Thanks, I am so stupid sometimes...Kind regards Lara:) |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-07-14 : 19:46:05
|
you can also use PIVOT operator. so query becomes likeSELECT *FROM(SELECT *FROM dbo.llattrdata A1Where ID = '434473')tPIVOT (MAX(ValStr) FOR AttrID IN ([5],[7],[10],[11]))p ------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
musclebreast
Yak Posting Veteran
77 Posts |
Posted - 2012-07-15 : 05:16:34
|
| Hi thanks,I learn really alot here.. I've never tried the pivot function, but in the future I will.Regarding this problem I've got a last question, hopefully:)I've got the following table:DataID.........time.....period.........start_point434473........ 2........week(s)........end of quarter443080........ 2........day(s).........end of yearAt first I need to convert the perio in days and have to calculate the day which I need to add to the start_point.days= time * periodSELECT ID, Enddate = CASE WHEN period = 'week(s)' then time * 7ENDFromTableThat works...With datedadd I can add the days..now my real problem...the column start_point...lets take the first example.the value is "end of quarter" Here I need to add the days to 4 dates30/03/201230/06/201230/09/201230/12/2012I,ve got two problems..1. Generate tat date of the current year. I tried it in this way:select convert(datetime, 'Jun 30 00:05:09' + CONVERT(CHAR(8), DATEPART (year, getdate() )) )Unfortunately it doesn't work.2. How can I write these 4 dates in one table?At this point i am not sure, because it's a bit complex.Do I have to use a user defined function or is it with the standard functions possible?Kind regards,Lara |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-07-15 : 22:13:43
|
for generating end of quarter days of current year usesomething like;With QuarterTable(EOQDate)AS(SELECT DATEADD(qq,1,DATEADD(yy,DATEDIFF(yy,0,GETDATE()),0)) -1 UNION ALL SELECT DATEADD(qq,1,EOQDate) FROM QuarterTable WHERE DATEADD(qq,1,EOQDate) <= DATEADD(yy,DATEDIFF(yy,0,GETDATE())+1,0))SELECT DataID,DATEADD(dd,CASE WHEN period = 'week(s)' then [time] * 7 WHEN period = 'day(s)' THEN [time] END,q.EOQDate)FROM YourTable tCROSS JOIN QuarterTable q ------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
musclebreast
Yak Posting Veteran
77 Posts |
Posted - 2012-07-24 : 19:57:21
|
| Hi,thanks for your answer. I never used ;with but it seems without used in an select it causes errors?I tried to combine it, because sometimes the start_point is half a year or each quarter.This is my table:DataID.........time.....period.........start_point434473........ 2........week(s)........end of quarter443080........ 2........day(s).........end half a yearfor the first row is must be than 4 rows and for the second entry it must be 2 rows. ;With QuarterTable(EOQDate)AS(SELECT DATEADD(qq,1,DATEADD(yy,DATEDIFF(yy,0,GETDATE()),0)) -1 UNION ALL SELECT DATEADD(qq,1,EOQDate) FROM QuarterTable WHERE DATEADD(qq,1,EOQDate) <= DATEADD(yy,DATEDIFF(yy,0,GETDATE())+1,0));With HalfTable1(EOQDate)AS(SELECT DATEADD(qq,2,DATEADD(yy,DATEDIFF(yy,0,GETDATE()),0)) -1 UNION ALL SELECT DATEADD(qq,2,EOQDate) FROM HalfTable1 WHERE DATEADD(qq,2,EOQDate) <= DATEADD(yy,DATEDIFF(yy,0,GETDATE())+1,0))How can I use ;With QuarterTable(EOQDate) and ;With HalfTable1(EOQDate) in one SQL query? Have you got an example or is that possible?Kind regards,Lara |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-07-24 : 23:05:16
|
| [code];With QuarterTable(EOQDate)AS(SELECT DATEADD(qq,1,DATEADD(yy,DATEDIFF(yy,0,GETDATE()),0)) -1UNION ALLSELECT DATEADD(qq,1,EOQDate)FROM QuarterTableWHERE DATEADD(qq,1,EOQDate) <= DATEADD(yy,DATEDIFF(yy,0,GETDATE())+1,0)), HalfTable1(EOQDate)AS(SELECT DATEADD(qq,2,DATEADD(yy,DATEDIFF(yy,0,GETDATE()),0)) -1UNION ALLSELECT DATEADD(qq,2,EOQDate)FROM HalfTable1WHERE DATEADD(qq,2,EOQDate) <= DATEADD(yy,DATEDIFF(yy,0,GETDATE())+1,0))--your select query using QuarterTable and HalfTable1[/code]------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
musclebreast
Yak Posting Veteran
77 Posts |
Posted - 2012-07-25 : 04:07:21
|
| Hi,thanks...oh you seperated the statements trhough a ,this was really helpful, because I've got alot more calculation there. One more question and I hope you can help me:;With QuarterTable(EOQDate)AS(SELECT DATEADD(qq,1,DATEADD(yy,DATEDIFF(yy,0,GETDATE()),0)) -1UNION ALLSELECT DATEADD(qq,1,EOQDate)FROM QuarterTableWHERE DATEADD(qq,1,EOQDate) <= DATEADD(yy,DATEDIFF(yy,0,GETDATE())+1,0)), HalfTable1(EOQDate)AS(SELECT DATEADD(qq,2,DATEADD(yy,DATEDIFF(yy,0,GETDATE()),0)) -1UNION ALLSELECT DATEADD(qq,2,EOQDate)FROM HalfTable1WHERE DATEADD(qq,2,EOQDate) <= DATEADD(yy,DATEDIFF(yy,0,GETDATE())+1,0))What I try doing is use only one table according to a value in a column...I tried it this way:select * from my table as tester CROSS JOINCASE WHEN tester.End_Spec = 'end of half-year' THEN HalfTable1 q END,CASE WHEN tester.End_Spec = 'quarter' THEN QuarterTable q ENDtester.End_Spec is a field in the table test.. I didn't wrote the sql statement, because then it's too complicated to understand...I hope you can see what i am trying and have a hint for me?kind regards,Lara |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-07-25 : 10:24:17
|
nope..i didnt get what you're trying to do here. my guess is this;With QuarterTable(EOQDate)AS(SELECT DATEADD(qq,1,DATEADD(yy,DATEDIFF(yy,0,GETDATE()),0)) -1UNION ALLSELECT DATEADD(qq,1,EOQDate)FROM QuarterTableWHERE DATEADD(qq,1,EOQDate) <= DATEADD(yy,DATEDIFF(yy,0,GETDATE())+1,0)), HalfTable1(EOQDate)AS(SELECT DATEADD(qq,2,DATEADD(yy,DATEDIFF(yy,0,GETDATE()),0)) -1UNION ALLSELECT DATEADD(qq,2,EOQDate)FROM HalfTable1WHERE DATEADD(qq,2,EOQDate) <= DATEADD(yy,DATEDIFF(yy,0,GETDATE())+1,0))SELECT *FROM my table as tester CROSS JOIN HalfTable1 WHERE tester.End_Spec = 'end of half-year' UNION ALLSELECT *FROM my table as tester CROSS JOIN QuarterTableWHERE tester.End_Spec = 'quarter' i didnt understand purpose of this though...can you elaborate?------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
musclebreast
Yak Posting Veteran
77 Posts |
Posted - 2012-07-25 : 17:30:17
|
| Hi,how could you know? it's xcactly want I needed. My generated table looks perfect now. Only one thing is left and now it's getting complicated.;With QuarterTable(EOQDate)AS(SELECT DATEADD(qq,1,DATEADD(yy,DATEDIFF(yy,0,GETDATE()),0)) -1UNION ALLSELECT DATEADD(qq,1,EOQDate)FROM QuarterTableWHERE DATEADD(qq,1,EOQDate) <= DATEADD(yy,DATEDIFF(yy,0,GETDATE())+1,0)), HalfTable1(EOQDate)AS(SELECT DATEADD(qq,2,DATEADD(yy,DATEDIFF(yy,0,GETDATE()),0)) -1UNION ALLSELECT DATEADD(qq,2,EOQDate)FROM HalfTable1WHERE DATEADD(qq,2,EOQDate) <= DATEADD(yy,DATEDIFF(yy,0,GETDATE())+1,0)),YearTable1(EOQDate)AS(SELECT DATEADD(qq,4,DATEADD(yy,DATEDIFF(yy,0,GETDATE()),0)) -1UNION ALLSELECT DATEADD(qq,4,EOQDate)FROM YearTable1WHERE DATEADD(qq,4,EOQDate) <= DATEADD(yy,DATEDIFF(yy,0,GETDATE())+1,0))SELECT tester.ID,tester.Effective_Date,tester.EndDate,EOQDate,CASE WHEN tester.Period = 'day(s)' THEN tester.Number WHEN tester.Period = 'week(s)' THEN tester.Number*7 WHEN tester.Period = 'month(s)' THEN tester.Number*30 END as days,tester.End_Spec,CASE WHEN tester.Period = 'day(s)' THEN convert(varchar,DATEADD(day,-tester.Number,EOQDate-30),103) WHEN tester.Period = 'week(s)' THEN convert(varchar,DATEADD(day,-30-tester.Number*7,EOQDate),103) WHEN tester.Period = 'month(s)' THEN convert(varchar,DATEADD(day,-30-tester.Number*30,EOQDate),103) END as Termination_DateFROM (SELECT * FROM(SELECT A1.ID,MAX(CASE WHEN AttrID = '4' THEN Valdate END) as Effective_Date, MAX(CaseWHEN AttrID = '5' THEN Valdate END) as Enddate,MAX(CaseWHEN AttrID = '7' THEN ValInt END) as Number, MAX(CaseWHEN AttrID = '10' THEN ValStr END) as Period, MAX(CaseWHEN AttrID = '11' THEN ValStr END) as End_SpecFROM dbo.llattrdata A1, dbo.dtree A2Where A2.DataID = A1.ID AND A1.DefID = '434818' AND A2.Subtype ='144' AND (A1.AttrID = '4' OR A1.AttrID = '7' OR A1.AttrID = '10' OR A1.AttrID = '11' OR A1.AttrID = '5') GROUP BY A1.ID) as tester1where tester1.Enddate IS NULL AND tester1.Number IS NOT NULL AND tester1.Period IS NOT NULL AND tester1.End_Spec IS NOT NULL AND tester1.End_Spec <> 'see description') as testerCROSS JOIN HalfTable1WHERE tester.End_Spec = 'end of half-year' UNION ALLSELECT tester.ID,tester.Effective_Date,tester.EndDate,EOQDate,CASE WHEN tester.Period = 'day(s)' THEN tester.Number WHEN tester.Period = 'week(s)' THEN tester.Number*7 WHEN tester.Period = 'month(s)' THEN tester.Number*30 END as days,tester.End_Spec,CASE WHEN tester.Period = 'day(s)' THEN convert(varchar,DATEADD(day,-tester.Number,EOQDate-30),103) WHEN tester.Period = 'week(s)' THEN convert(varchar,DATEADD(day,-30-tester.Number*7,EOQDate),103) WHEN tester.Period = 'month(s)' THEN convert(varchar,DATEADD(day,-30-tester.Number*30,EOQDate),103) END as Termination_Date FROM (SELECT * FROM(SELECT A1.ID,MAX(CASE WHEN AttrID = '4' THEN Valdate END) as Effective_Date, MAX(CaseWHEN AttrID = '5' THEN Valdate END) as Enddate,MAX(CaseWHEN AttrID = '7' THEN ValInt END) as Number, MAX(CaseWHEN AttrID = '10' THEN ValStr END) as Period, MAX(CaseWHEN AttrID = '11' THEN ValStr END) as End_SpecFROM dbo.llattrdata A1, dbo.dtree A2Where A2.DataID = A1.ID AND A1.DefID = '434818' AND A2.Subtype ='144' AND (A1.AttrID = '4' OR A1.AttrID = '7' OR A1.AttrID = '10' OR A1.AttrID = '11' OR A1.AttrID = '5') GROUP BY A1.ID) as tester1where tester1.Enddate IS NULL AND tester1.Number IS NOT NULL AND tester1.Period IS NOT NULL AND tester1.End_Spec IS NOT NULL AND tester1.End_Spec <> 'see description') as testerCROSS JOIN QuarterTableWHERE tester.End_Spec = 'end of quarter' Hopefulley it's not too much..in the end the problem is easy...I want only the entries where the termination date is equal the current date.I tried it this way:WHERE tester.End_Spec = 'end of quarter' AND Termination_Date = convert(varchar, getdate(), 103)I get an error that the system doesn't know the column Termination_Date...my secodn attempt: I wanted to do a new sql from my generated table:;With QuarterTable(EOQDate)AS(SELECT DATEADD(qq,1,DATEADD(yy,DATEDIFF(yy,0,GETDATE()),0)) -1UNION ALLSELECT DATEADD(qq,1,EOQDate)FROM QuarterTableWHERE DATEADD(qq,1,EOQDate) <= DATEADD(yy,DATEDIFF(yy,0,GETDATE())+1,0)), HalfTable1(EOQDate)AS(SELECT DATEADD(qq,2,DATEADD(yy,DATEDIFF(yy,0,GETDATE()),0)) -1UNION ALLSELECT DATEADD(qq,2,EOQDate)FROM HalfTable1WHERE DATEADD(qq,2,EOQDate) <= DATEADD(yy,DATEDIFF(yy,0,GETDATE())+1,0))SELECT *FROM(SELECT *FROM my table as tester CROSS JOIN HalfTable1 WHERE tester.End_Spec = 'end of half-year' UNION ALLSELECT *FROM my table as tester CROSS JOIN QuarterTableWHERE tester.End_Spec = 'quarter') where Termination_Date...It seems this is not possible as well...where can I do the request.. I've been trying hours but sometimes i am too stupid.:)Kind regards,Lara |
 |
|
|
Next Page
|
|
|
|
|