I'm not an expert at SQL and i'm not even sure if this type of query is doable.
I want to return a count(*) for each "MediaTypeID" for each Month based off of "MediaDate".
Any help would be greatly appreciated!
Thanks.
My Table looks like:
The Table Data looks like:
1 | 1 | Funny Cat Video | 2006-01-25 00:00:00.000
2 | 1 | Funny Dog Video | 2006-01-20 00:00:00.000
3 | 2 | Angry Birds Game | 2006-03-13 00:00:00.000
4 | 4 | Blonde Joke | 2006-03-16 00:00:00.000
5 | 3 | Goofy Clown Picture | 2006-02-27 00:00:00.000
6 | 2 | Racing Game | 2006-02-10 00:00:00.000
7 | 1 | Star Wars Video | 2006-07-15 00:00:00.000
The query would return 12 rows of results for Jan-Dec looking like:
Month | MediaTypeID1Count | MediaTypeID2Count | MediaTypeID3Count | MediaTypeID4Count
Jan | 400 | 255 | 15 | 65
Feb | 100 | 25 | 75 | 35
Mar | 320 | 155 | 50 | 99
Apr | 56 | 0 | 98 | 313
This type of data transformation is known as a PIVOT
. SQL Server 2005+ has a pivot function that can be implemented:
select month,
[1] MediaType1_count,
[2] MediaType2_count,
[3] MediaType3_count,
[4] MediaType4_count
from
(
select
mediatypeid,
datename(m, mediadate) Month,
datepart(m, mediadate) monnum
from yourtable
) src
pivot
(
count(mediatypeid)
for mediatypeid in ([1], [2], [3], [4])
) piv
order by monnum
If you have an unknown number of values that you want to transpose into columns, then you can use dynamic sql:
DECLARE @cols AS NVARCHAR(MAX),
@colNames AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(mediatypeid)
from yourtable
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
select @colNames = STUFF((SELECT distinct ', ' + QUOTENAME(mediatypeid) +' as MediaType' + cast(mediatypeid as varchar(50))+'_Count'
from yourtable
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT month,' + @colNames + ' from
(
select mediatypeid,
datename(m, mediadate) Month,
datepart(m, mediadate) monnum
from yourtable
) x
pivot
(
count(mediatypeid)
for mediatypeid in (' + @cols + ')
) p
order by monnum'
execute(@query)
The result will look like:
| MONTH | MEDIATYPE1_COUNT | MEDIATYPE2_COUNT | MEDIATYPE3_COUNT | MEDIATYPE4_COUNT |
----------------------------------------------------------------------------------------
| January | 2 | 0 | 0 | 0 |
| February | 0 | 1 | 1 | 0 |
| March | 0 | 1 | 0 | 1 |
| July | 1 | 0 | 0 | 0 |
I think this may be what you are looking for. The following will simply return the count based off the media type id, then group by year and then its month
Select MediaTypeID, datepart(year, MediaDate), datepart(month, MediaDate), count(*)
From Media
Group by MediaTypeID, datepart(year, MediaDate), datepart(month, MediaDate)
In my opinion, this could be a good challenge for you to start with this code:
Declare @T Table (
MediaID BigInt Primary Key Identity(1, 1)
, MediaTypeID BigInt
, MediaTitle Nvarchar(50)
, MediaDate DateTime
);
Insert @T (
MediaTypeID
, MediaTitle
, MediaDate
) Select 1
, 'Funny Cat Video'
, '2006-01-25 00:00:00.000'
Union
Select 1
, 'Funny Dog Video'
, '2006-01-20 00:00:00.000'
Union
Select 2
, 'Angry Birds Game'
, '2006-03-13 00:00:00.000'
Union
Select 4
, 'Blonde Joke'
, '2006-03-16 00:00:00.000'
Union
Select 3
, 'Goofy Clown Picture'
, '2006-02-27 00:00:00.000'
Union
Select 2
, 'Racing Game'
, '2006-02-10 00:00:00.000'
Union
Select 1
, 'Star Wars Video'
, '2006-07-15 00:00:00.000'
;
Select Month.Title
, Count(Type01_Result.MediaID) As MediaTypeID_1
, Count(Type02_Result.MediaID) As MediaTypeID_2
, Count(Type03_Result.MediaID) As MediaTypeID_3
, Count(Type04_Result.MediaID) As MediaTypeID_4
From (
Select 1 As Id
, 'Jan' As Title
Union
Select 2
, 'Feb'
Union
Select 3
, 'March'
Union
Select 4
, 'April'
Union
Select 5
, 'May'
Union
Select 6
, 'June'
Union
Select 7
, 'July'
Union
Select 8
, 'Aug'
Union
Select 9
, 'Sept'
Union
Select 10
, 'Nov'
Union
Select 11
, 'Oct'
Union
Select 12
, 'Dec'
) As Month
Left Outer Join
@T As Type01_Result
On Type01_Result.MediaTypeID = 1
And DatePart(Month, Type01_Result.MediaDate) = Month.Id
Left Outer Join
@T As Type02_Result
On Type02_Result.MediaTypeID = 2
And DatePart(Month, Type02_Result.MediaDate) = Month.Id
Left Outer Join
@T As Type03_Result
On Type03_Result.MediaTypeID = 3
And DatePart(Month, Type03_Result.MediaDate) = Month.Id
Left Outer Join
@T As Type04_Result
On Type04_Result.MediaTypeID = 4
And DatePart(Month, Type04_Result.MediaDate) = Month.Id
Group By Month.Title
;
The only thing is that you should be carefull about the year value and how many years you wanna include in the output, because this result will give you the summation of all records in each month no matter which year the date of the record is. It may cause some confusion in the result.
(Remember that I always set the tab size to 8 characters in the Options of Management Studio, so I suggest you do that to see the correct style of writing T-SQL)
Hope it helps you.
Cheers
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.