SQL Clone
SQLServerCentral is supported by Redgate
 
Log in  ::  Register  ::  Not logged in
 
 
 


Turning raw data into a grid layout


Turning raw data into a grid layout

Author
Message
Tava
Tava
Right there with Babe
Right there with Babe (729 reputation)Right there with Babe (729 reputation)Right there with Babe (729 reputation)Right there with Babe (729 reputation)Right there with Babe (729 reputation)Right there with Babe (729 reputation)Right there with Babe (729 reputation)Right there with Babe (729 reputation)

Group: General Forum Members
Points: 729 Visits: 806
Hi all,

not sure how best to explain what I'm trying to do so will try to break it down as easy as i can.

I have a table which stores all prices for companies daily trading. Companies ABC & XYZ have information available for what was the high & low values for a DateID.




CREATE TABLE [dbo].[TestGrid]
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[CompanyName] [varchar](200) NOT NULL,
[DateID] [int] NOT NULL,
[High] [float] NOT NULL,
[Low] [float] NOT NULL
)

INSERT INTO [dbo].[TestGrid] (CompanyName,DateID,High,Low)
VALUES ('ABC',20121201,0.5,1.0)

INSERT INTO [dbo].[TestGrid] (CompanyName,DateID,High,Low)
VALUES ('ABC',20121202,0.6,1.5)

INSERT INTO [dbo].[TestGrid] (CompanyName,DateID,High,Low)
VALUES ('ABC',20121203,1.0,1.6)


INSERT INTO [dbo].[TestGrid] (CompanyName,DateID,High,Low)
VALUES ('XYZ',20121201,0.5,0.4)

INSERT INTO [dbo].[TestGrid] (CompanyName,DateID,High,Low)
VALUES ('XYZ',20121202,0.6,0.5)

INSERT INTO [dbo].[TestGrid] (CompanyName,DateID,High,Low)
VALUES ('XYZ',20121203,1.0,0.6)






ID CompanyName DateID High Low
----------- ----------------------------------------------------------
1 ABC 20121201 0.5 0.1
2 ABC 20121202 0.6 0.5
3 ABC 20121203 1 0.6
4 XYZ 20121201 0.5 0.4
5 XYZ 20121202 0.6 0.5
6 XYZ 20121203 1 0.6






What I'm trying to do is turn the DateID into columns and then as a additional change those columns represent the actual day of the Date ID How would i know 20121201 is equal to say Monday and 02 is Tuesday?


END RESULT:



NAME TYPE MONDAY TUESDAY WEDNESDAY
ABC HIGH 0.5 0.6 1
ABC LOW 0.1 1.5 0.6




I'm not sure if cross join / pivot or something else should be used so if i could get a hand would be great
dwain.c
dwain.c
SSCoach
SSCoach (17K reputation)SSCoach (17K reputation)SSCoach (17K reputation)SSCoach (17K reputation)SSCoach (17K reputation)SSCoach (17K reputation)SSCoach (17K reputation)SSCoach (17K reputation)

Group: General Forum Members
Points: 17035 Visits: 6431
You might try this:


SELECT CompanyName, Type
,Sunday=MAX(CASE WHEN weekday = 1 THEN Val END)
,Monday=MAX(CASE WHEN weekday = 2 THEN Val END)
,Tuesday=MAX(CASE WHEN weekday = 3 THEN Val END)
,Wednesday=MAX(CASE WHEN weekday = 4 THEN Val END)
,Thursday=MAX(CASE WHEN weekday = 5 THEN Val END)
,Friday=MAX(CASE WHEN weekday = 6 THEN Val END)
,Saturday=MAX(CASE WHEN weekday = 7 THEN Val END)
FROM dbo.TestGrid
CROSS APPLY (
VALUES(High, 'High', DATEPART(dw, CAST(DateID AS CHAR(8))))
,(Low, 'Low', DATEPART(dw, CAST(DateID AS CHAR(8))))) a(Val, Type, weekday)
GROUP BY CompanyName, Type




And you will also want to Google "SQL DATEFIRST" to see how this query is sensitive to that setting.

You can look at the first link in my signature to see how the CROSS APPLY VALUES works (like an UNPIVOT but usually faster).

I won't ask (but should) why (before someone else does) you're storing a date as an INT instead of a DATETIME.


My mantra: No loops! No CURSORs! No RBAR! Hoo-uh!

My thought question: Have you ever been told that your query runs too fast?

My advice:
INDEXing a poor-performing query is like putting sugar on cat food. Yeah, it probably tastes better but are you sure you want to eat it?
The path of least resistance can be a slippery slope. Take care that fixing your fixes of fixes doesn't snowball and end up costing you more than fixing the root cause would have in the first place.


Need to UNPIVOT? Why not CROSS APPLY VALUES instead?
Since random numbers are too important to be left to chance, let's generate some!
Learn to understand recursive CTEs by example.
Splitting strings based on patterns can be fast!
My temporal SQL musings: Calendar Tables, an Easter SQL, Time Slots and Self-maintaining, Contiguous Effective Dates in Temporal Tables
Lynn Pettis
Lynn Pettis
SSC Guru
SSC Guru (91K reputation)SSC Guru (91K reputation)SSC Guru (91K reputation)SSC Guru (91K reputation)SSC Guru (91K reputation)SSC Guru (91K reputation)SSC Guru (91K reputation)SSC Guru (91K reputation)

Group: General Forum Members
Points: 91114 Visits: 38945
dwain.c (1/1/2013)
You might try this:


SELECT CompanyName, Type
,Sunday=MAX(CASE WHEN weekday = 1 THEN Val END)
,Monday=MAX(CASE WHEN weekday = 2 THEN Val END)
,Tuesday=MAX(CASE WHEN weekday = 3 THEN Val END)
,Wednesday=MAX(CASE WHEN weekday = 4 THEN Val END)
,Thursday=MAX(CASE WHEN weekday = 5 THEN Val END)
,Friday=MAX(CASE WHEN weekday = 6 THEN Val END)
,Saturday=MAX(CASE WHEN weekday = 7 THEN Val END)
FROM dbo.TestGrid
CROSS APPLY (
VALUES(High, 'High', DATEPART(dw, CAST(DateID AS CHAR(8))))
,(Low, 'Low', DATEPART(dw, CAST(DateID AS CHAR(8))))) a(Val, Type, weekday)
GROUP BY CompanyName, Type




And you will also want to Google "SQL DATEFIRST" to see how this query is sensitive to that setting.

You can look at the first link in my signature to see how the CROSS APPLY VALUES works (like an UNPIVOT but usually faster).

I won't ask (but should) why (before someone else does) you're storing a date as an INT instead of a DATETIME.


Try this, it shouldn't be sensitive to the DATEFIRST setting. It relies on 1900-01-01 being a Monday.



SELECT
CompanyName
,Type
,Sunday = MAX(CASE WHEN weekday = datename(dw, dateadd(dd, 1 - 2, '19000101')) THEN Val END)
,Monday = MAX(CASE WHEN weekday = datename(dw, dateadd(dd, 2 - 2, '19000101')) THEN Val END)
,Tuesday = MAX(CASE WHEN weekday = datename(dw, dateadd(dd, 3 - 2, '19000101')) THEN Val END)
,Wednesday = MAX(CASE WHEN weekday = datename(dw, dateadd(dd, 4 - 2, '19000101')) THEN Val END)
,Thursday = MAX(CASE WHEN weekday = datename(dw, dateadd(dd, 5 - 2, '19000101')) THEN Val END)
,Friday = MAX(CASE WHEN weekday = datename(dw, dateadd(dd, 6 - 2, '19000101')) THEN Val END)
,Saturday = MAX(CASE WHEN weekday = datename(dw, dateadd(dd, 7 - 2, '19000101')) THEN Val END)
FROM dbo.TestGrid
CROSS APPLY (
VALUES(High, 'High', DATENAME(dw, CAST(DateID AS CHAR(8))))
,(Low, 'Low', DATENAME(dw, CAST(DateID AS CHAR(8))))) a(Val, Type, weekday)
GROUP BY CompanyName, Type;




Cool
Lynn Pettis

For better assistance in answering your questions, click here
For tips to get better help with Performance Problems, click here
For Running Totals and its variations, click here or when working with partitioned tables
For more about Tally Tables, click here
For more about Cross Tabs and Pivots, click here and here
Managing Transaction Logs

SQL Musings from the Desert Fountain Valley SQL (My Mirror Blog)
Tava
Tava
Right there with Babe
Right there with Babe (729 reputation)Right there with Babe (729 reputation)Right there with Babe (729 reputation)Right there with Babe (729 reputation)Right there with Babe (729 reputation)Right there with Babe (729 reputation)Right there with Babe (729 reputation)Right there with Babe (729 reputation)

Group: General Forum Members
Points: 729 Visits: 806
Thanks guys, i've tried both and both get the same results as i expected. I thought i had use cross apply just wasn't too sure how to use it to get what i expected.

To answer the question about why is DateID int and not datetime its an old table and data already in there. I assume its for an indexing/performance benefit and everything is based on dateid for searching? does that sound about right?
dwain.c
dwain.c
SSCoach
SSCoach (17K reputation)SSCoach (17K reputation)SSCoach (17K reputation)SSCoach (17K reputation)SSCoach (17K reputation)SSCoach (17K reputation)SSCoach (17K reputation)SSCoach (17K reputation)

Group: General Forum Members
Points: 17035 Visits: 6431
Tava (1/2/2013)

To answer the question about why is DateID int and not datetime its an old table and data already in there. I assume its for an indexing/performance benefit and everything is based on dateid for searching? does that sound about right?



It is not the first time I've heard of someone being stuck with a legacy design. If you're in SQL 2008 and designing anew, using DATE datatype would provide the same indexing/performance benefit as what you've done. I actually doubt there would be a difference had the field been created as a DATETIME (just perhaps a little more application housekeeping to ensure that no time part is stored with it).

Lynn - Nice way to eliminate the dependency on DATEFIRST.


My mantra: No loops! No CURSORs! No RBAR! Hoo-uh!

My thought question: Have you ever been told that your query runs too fast?

My advice:
INDEXing a poor-performing query is like putting sugar on cat food. Yeah, it probably tastes better but are you sure you want to eat it?
The path of least resistance can be a slippery slope. Take care that fixing your fixes of fixes doesn't snowball and end up costing you more than fixing the root cause would have in the first place.


Need to UNPIVOT? Why not CROSS APPLY VALUES instead?
Since random numbers are too important to be left to chance, let's generate some!
Learn to understand recursive CTEs by example.
Splitting strings based on patterns can be fast!
My temporal SQL musings: Calendar Tables, an Easter SQL, Time Slots and Self-maintaining, Contiguous Effective Dates in Temporal Tables
Lynn Pettis
Lynn Pettis
SSC Guru
SSC Guru (91K reputation)SSC Guru (91K reputation)SSC Guru (91K reputation)SSC Guru (91K reputation)SSC Guru (91K reputation)SSC Guru (91K reputation)SSC Guru (91K reputation)SSC Guru (91K reputation)

Group: General Forum Members
Points: 91114 Visits: 38945
dwain.c (1/2/2013)
Tava (1/2/2013)

To answer the question about why is DateID int and not datetime its an old table and data already in there. I assume its for an indexing/performance benefit and everything is based on dateid for searching? does that sound about right?



It is not the first time I've heard of someone being stuck with a legacy design. If you're in SQL 2008 and designing anew, using DATE datatype would provide the same indexing/performance benefit as what you've done. I actually doubt there would be a difference had the field been created as a DATETIME (just perhaps a little more application housekeeping to ensure that no time part is stored with it).

Lynn - Nice way to eliminate the dependency on DATEFIRST.


I don't think it works the way I expected it to, looks like it is missing part of the code due to a poor copy and past. I'll have to look at later when I get back to the apartment.

Cool
Lynn Pettis

For better assistance in answering your questions, click here
For tips to get better help with Performance Problems, click here
For Running Totals and its variations, click here or when working with partitioned tables
For more about Tally Tables, click here
For more about Cross Tabs and Pivots, click here and here
Managing Transaction Logs

SQL Musings from the Desert Fountain Valley SQL (My Mirror Blog)
dwain.c
dwain.c
SSCoach
SSCoach (17K reputation)SSCoach (17K reputation)SSCoach (17K reputation)SSCoach (17K reputation)SSCoach (17K reputation)SSCoach (17K reputation)SSCoach (17K reputation)SSCoach (17K reputation)

Group: General Forum Members
Points: 17035 Visits: 6431
Lynn Pettis (1/2/2013)
dwain.c (1/2/2013)
Tava (1/2/2013)

To answer the question about why is DateID int and not datetime its an old table and data already in there. I assume its for an indexing/performance benefit and everything is based on dateid for searching? does that sound about right?



It is not the first time I've heard of someone being stuck with a legacy design. If you're in SQL 2008 and designing anew, using DATE datatype would provide the same indexing/performance benefit as what you've done. I actually doubt there would be a difference had the field been created as a DATETIME (just perhaps a little more application housekeeping to ensure that no time part is stored with it).

Lynn - Nice way to eliminate the dependency on DATEFIRST.


I don't think it works the way I expected it to, looks like it is missing part of the code due to a poor copy and past. I'll have to look at later when I get back to the apartment.


Hehe. I didn't try to run it but understood what you were trying to do. I think you meant this (in the CASE statements):


SELECT datename(dw, dateadd(day, 1 - 2, '19000101')) -- for Sunday





My mantra: No loops! No CURSORs! No RBAR! Hoo-uh!

My thought question: Have you ever been told that your query runs too fast?

My advice:
INDEXing a poor-performing query is like putting sugar on cat food. Yeah, it probably tastes better but are you sure you want to eat it?
The path of least resistance can be a slippery slope. Take care that fixing your fixes of fixes doesn't snowball and end up costing you more than fixing the root cause would have in the first place.


Need to UNPIVOT? Why not CROSS APPLY VALUES instead?
Since random numbers are too important to be left to chance, let's generate some!
Learn to understand recursive CTEs by example.
Splitting strings based on patterns can be fast!
My temporal SQL musings: Calendar Tables, an Easter SQL, Time Slots and Self-maintaining, Contiguous Effective Dates in Temporal Tables
Lynn Pettis
Lynn Pettis
SSC Guru
SSC Guru (91K reputation)SSC Guru (91K reputation)SSC Guru (91K reputation)SSC Guru (91K reputation)SSC Guru (91K reputation)SSC Guru (91K reputation)SSC Guru (91K reputation)SSC Guru (91K reputation)

Group: General Forum Members
Points: 91114 Visits: 38945
dwain.c (1/2/2013)
Lynn Pettis (1/2/2013)
dwain.c (1/2/2013)
Tava (1/2/2013)

To answer the question about why is DateID int and not datetime its an old table and data already in there. I assume its for an indexing/performance benefit and everything is based on dateid for searching? does that sound about right?



It is not the first time I've heard of someone being stuck with a legacy design. If you're in SQL 2008 and designing anew, using DATE datatype would provide the same indexing/performance benefit as what you've done. I actually doubt there would be a difference had the field been created as a DATETIME (just perhaps a little more application housekeeping to ensure that no time part is stored with it).

Lynn - Nice way to eliminate the dependency on DATEFIRST.


I don't think it works the way I expected it to, looks like it is missing part of the code due to a poor copy and past. I'll have to look at later when I get back to the apartment.


Hehe. I didn't try to run it but understood what you were trying to do. I think you meant this (in the CASE statements):


SELECT datename(dw, dateadd(day, 1 - 2, '19000101')) -- for Sunday




Should also take care of language differences.

Cool
Lynn Pettis

For better assistance in answering your questions, click here
For tips to get better help with Performance Problems, click here
For Running Totals and its variations, click here or when working with partitioned tables
For more about Tally Tables, click here
For more about Cross Tabs and Pivots, click here and here
Managing Transaction Logs

SQL Musings from the Desert Fountain Valley SQL (My Mirror Blog)
Bhuvnesh
Bhuvnesh
SSChampion
SSChampion (12K reputation)SSChampion (12K reputation)SSChampion (12K reputation)SSChampion (12K reputation)SSChampion (12K reputation)SSChampion (12K reputation)SSChampion (12K reputation)SSChampion (12K reputation)

Group: General Forum Members
Points: 12714 Visits: 4077
i tried it with PIVOT but its more resource intensive (as compared to other provided solution ) . can we avoid UNION here



SELECT CompanyName, 'Low' as Type,
[Sunday], [Monday], [tuesday], [wednesday], [thursday],[Friday],[Saturday]
FROM
(
select
CompanyName,
Low,
CASE
WHEN DATEPART(dw, CAST(DateID AS CHAR(8))) = 1 THEN 'Sunday'
WHEN DATEPART(dw, CAST(DateID AS CHAR(8))) = 2 THEN 'Monday'
WHEN DATEPART(dw, CAST(DateID AS CHAR(8))) = 3 THEN 'tuesday'
WHEN DATEPART(dw, CAST(DateID AS CHAR(8))) = 4 THEN 'wednesday'
WHEN DATEPART(dw, CAST(DateID AS CHAR(8))) = 5 THEN 'thursday'
WHEN DATEPART(dw, CAST(DateID AS CHAR(8))) = 6 THEN 'Friday'
WHEN DATEPART(dw, CAST(DateID AS CHAR(8))) = 7 THEN 'Saturday'
END as WeekDays
from [TestGrid]
) AS SourceTable
PIVOT
(
SUM(Low)
FOR WeekDays IN ([Sunday], [Monday], [tuesday], [wednesday], [thursday],[Friday],[Saturday])
) AS PivotTable
UNION
SELECT CompanyName, 'High' as Type,
[Sunday], [Monday], [tuesday], [wednesday], [thursday],[Friday],[Saturday]
FROM
(
select
CompanyName,
High,
CASE
WHEN DATEPART(dw, CAST(DateID AS CHAR(8))) = 1 THEN 'Sunday'
WHEN DATEPART(dw, CAST(DateID AS CHAR(8))) = 2 THEN 'Monday'
WHEN DATEPART(dw, CAST(DateID AS CHAR(8))) = 3 THEN 'tuesday'
WHEN DATEPART(dw, CAST(DateID AS CHAR(8))) = 4 THEN 'wednesday'
WHEN DATEPART(dw, CAST(DateID AS CHAR(8))) = 5 THEN 'thursday'
WHEN DATEPART(dw, CAST(DateID AS CHAR(8))) = 6 THEN 'Friday'
WHEN DATEPART(dw, CAST(DateID AS CHAR(8))) = 7 THEN 'Saturday'
END as WeekDays
from [TestGrid]
) AS SourceTable
PIVOT
(
SUM(High)
FOR WeekDays IN ([Sunday], [Monday], [tuesday], [wednesday], [thursday],[Friday],[Saturday])
) AS PivotTable



-------Bhuvnesh----------
I work only to learn Sql Server...though my company pays me for getting their stuff done;-)
Bhuvnesh
Bhuvnesh
SSChampion
SSChampion (12K reputation)SSChampion (12K reputation)SSChampion (12K reputation)SSChampion (12K reputation)SSChampion (12K reputation)SSChampion (12K reputation)SSChampion (12K reputation)SSChampion (12K reputation)

Group: General Forum Members
Points: 12714 Visits: 4077
dwain.c (1/1/2013)


CROSS APPLY (
VALUES(High, 'High', DATEPART(dw, CAST(DateID AS CHAR(8))))
,(Low, 'Low', DATEPART(dw, CAST(DateID AS CHAR(8))))) a(Val, Type, weekday)
GROUP BY CompanyName, Type

dwain , can you please explain above sql code , i am finding it hard to understand Sick

-------Bhuvnesh----------
I work only to learn Sql Server...though my company pays me for getting their stuff done;-)
Go


Permissions

You can't post new topics.
You can't post topic replies.
You can't post new polls.
You can't post replies to polls.
You can't edit your own topics.
You can't delete your own topics.
You can't edit other topics.
You can't delete other topics.
You can't edit your own posts.
You can't edit other posts.
You can't delete your own posts.
You can't delete other posts.
You can't post events.
You can't edit your own events.
You can't edit other events.
You can't delete your own events.
You can't delete other events.
You can't send private messages.
You can't send emails.
You can read topics.
You can't vote in polls.
You can't upload attachments.
You can download attachments.
You can't post HTML code.
You can't edit HTML code.
You can't post IFCode.
You can't post JavaScript.
You can post emoticons.
You can't post or upload images.

Select a forum

































































































































































SQLServerCentral


Search