how to use PIVOT to get required results [duplicate] - sql

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
convert one row into columns.
This is my query.
DECLARE #temp TABLE
(
MonthName VARCHAR(10),
[Year] VARCHAR(10),
StatusTypeId INT,
StatusTypeName VARCHAR(50),
StatusCount INT
)
INSERT INTO #temp
SELECT
CONVERT(varchar(3), DATENAME(month, w.ExpectedStartDate)) as MonthName,
datepart(yyyy, w.ExpectedStartDate) as [Year],
w.StatusTypeId,
st.StatusTypeName,
COUNT(ISNULL(w.StatusTypeId, 0)) AS StatusCount
FROM
Worksheet w LEFT OUTER JOIN
StatusType st ON st.StatusTypeId = w.StatusTypeId
WHERE w.ProjectId = 20
AND CONVERT(varchar(3), DATENAME(month, w.ExpectedStartDate)) between ('feb') AND ('mar')
GROUP BY
datepart(yyyy, w.ExpectedStartDate),
CONVERT(varchar(3), DATENAME(month, w.ExpectedStartDate)),
w.StatusTypeId,
st.StatusTypeName
SELECT ISNULL(((CONVERT(VARCHAR(5), [Year])) + '-' + MonthName), 'Unknown') AS MonthName,
ISNULL(StatusTypeName, 'Unknown') AS StatusTypeName,
StatusCount
FROM #temp
I want result like this.
Please guide me.
Thanks.

Eg.
select
*
from
(
select
monthname,statustypename
from yourtable
) DataTable
PIVOT
(
SUM(statuscount)
FOR statustypename
IN (
[tobescheduled],[complete]
)
) PivotTable
Also check the link
http://geekswithblogs.net/lorint/archive/2006/08/04/87166.aspx

Related

Years separated by comma CTE in SQL Server

I have a field called StartYear, the value of my field is 2000. I have another field called EndYear, the value of my field is 2005.
I want to create a field called YearsInTheProgram that has the values 2005,2004, 2003,2002,2001,2000.
Each of my rows have different values, so in essence I would like this field to have the difference of my fields separated my commas.
I was able to find something that would work, but this would give me a value in different rows. However, I want all of them in one row.
with CTE as
(
select datepart(year, '2006-12-25') as yr
union all
select yr + 1
from CTE
where yr < datepart(year, '2013-11-14')
)
select yr
from CTE
declare #tmp varchar(250)
SET #tmp = ''
;with CTE as
(
select datepart(year, '2006-12-25') as yr
union all
select yr + 1
from CTE
where yr < datepart(year, '2013-11-14')
)
select #tmp = #tmp + convert(varchar(500), yr) + ', ' from CTE
select SUBSTRING(#tmp, 0, LEN(#tmp)) as yr
You can bulid up your string of years using this CTE.
DECLARE #STARTYEAR varchar(10) = '2006-12-25'
DECLARE #ENDYEAR varchar(10) = '2013-11-14'
;with CTE as
(
select datepart(year, #STARTYEAR) as yr, CAST(datepart(year, #STARTYEAR) AS VARCHAR(MAX)) as c
union all
select yr + 1 as yr, CAST(concat(c, ',', yr+1) AS VARCHAR(MAX)) as c
from CTE
where yr < datepart(year, #ENDYEAR)
)
select yr, c
from CTE
where (yr = datepart(year, #ENDYEAR))
And here it is with StartYear and EndYear taken from DB table.
create table #yr (id int, start varchar(20), stop varchar(20))
insert into #yr values(1,'2005-01-01','2010-12-10'), (2,'2008-01-01','2011-12-10'), (3,'2007-01-01','2013-12-10'), (4,'2009-01-01','2012-10-10')
;with CTE as
(
select start as start, datepart(year, start) as yr, CAST(datepart(year, start) AS VARCHAR(MAX)) as c from #yr
union all
select CTE.start as start, yr + 1 as yr, CAST(concat(c, ',', yr+1) AS VARCHAR(MAX)) as c
from CTE join #yr on #yr.start = CTE.start
where yr < datepart(year, stop)
)
select id, #yr.start, #yr.stop, c
from CTE join #yr on #yr.start = CTE.start
where (yr = datepart(year, stop))
With following result
4 2009-01-01 2012-10-10 2009,2010,2011,2012
3 2007-01-01 2013-12-10 2007,2008,2009,2010,2011,2012,2013
2 2008-01-01 2011-12-10 2008,2009,2010,2011
1 2005-01-01 2010-12-10 2005,2006,2007,2008,2009,2010

SQL Server : duplicate counts

I have the following. But in the final result some of the employee ID's are counted twice. My goal is to only count distinct employeeID for the [UniqueEmployees] column... Can someone please help me?
This is the code here:
IF OBJECT_ID(N'tempdb..#GG') IS NOT NULL
DROP TABLE #GG
SELECT DISTINCT
[month], vv.Hiremonth,
LoanNumber, vv.EmployeeId,
agentname,
vv.YearsOfService, vv.MonthsofService,
vv.TenureGrouping, vv.TenureMonthGrouping,
manager,
SUM([Call Counts]) as Calls,
SUM(opportunities) as Opportunities,
SUM([Discussed w/Customer]) as [Discussed w/Customer],
SUM(DidNotDiscuss) as [DidNotDiscuss],
SUM(CustomerInterested) as CustomerInterested,
(SELECT COUNT(DISTINCT MGR.EmployeeId)
FROM #MANAGERS MGR
WHERE --EmployeeId = EmployeeId
--and
CAST(CONVERT(datetime, RIGHT(MGR.HireMonth, 4) + LEFT(MGR.HireMonth, 2) + '01') as DATE) <= CAST(CONVERT(datetime, right([Month], 4) + left([Month], 2) + '01') as DATE)
--and MonthsOfService = MonthsOfService
--and YearsOfService = YearsOfService
) as UniqueEmployees
INTO
#GG
FROM
#FINALtemp2b VV
--left join
--(select distinct Employeeid
--from #FINALtemp2b) CC
--on CC.EmployeeId = VV.EmployeeId
GROUP BY
[month], vv.Hiremonth, LoanNumber, vv.EmployeeId,
agentname, vv.YearsOfService, vv.MonthsofService,
vv.TenureGrouping, vv.TenureMonthGrouping, manager
ORDER BY
[month]
Try removing the first 'distinct' and the excess 'select'.
IF OBJECT_ID(N'tempdb..#GG') is not null Drop Table #GG
select *
into #GG
from (
select
[month],
vv.Hiremonth,
LoanNumber,
vv.EmployeeId,
agentname,
vv.YearsOfService,
vv.MonthsofService,
vv.TenureGrouping,
vv.TenureMonthGrouping,
manager,
SUM([Call Counts]) as Calls,
sum(opportunities) as Opportunities,
sum([Discussed w/Customer]) as [Discussed w/Customer],
sum(DidNotDiscuss) as [DidNotDiscuss],
sum(CustomerInterested) as CustomerInterested,
count(distinct (MGR.EmployeeId))
from #MANAGERS MGR
where cast(convert(datetime,right(MGR.HireMonth,4) + left(MGR.HireMonth,2) + '01') as DATE) <= cast(convert(datetime,right([Month],4) + left([Month],2) + '01') as DATE)
group by
[month],
vv.Hiremonth,
LoanNumber,
vv.EmployeeId,
agentname,
vv.YearsOfService,
vv.MonthsofService,
vv.TenureGrouping,
vv.TenureMonthGrouping,
manager
) as UniqueEmployees

Sql server issue ORDER BY clause is invalid in views

Here I am going to post my full stored procedure code then I will pick the area which is giving error.
ALTER PROC [dbo].[WarrantyTrends]
(
#StartYr AS INT,
#EndYr AS INT
)
AS
DECLARE #query varchar(max)
DECLARE #years varchar(max), #yearsColumns varchar(max)
SELECT 1 mID, 'January' as month into #tempMonths UNION ALL
SELECT 2,'February' as month UNION ALL
SELECT 3,'March' as month UNION ALL
SELECT 4,'April' as month UNION ALL
SELECT 5,'May' as month UNION ALL
SELECT 6,'June' as month UNION ALL
SELECT 7,'July' as month UNION ALL
SELECT 8,'August' as month UNION ALL
SELECT 9,'September' as month UNION ALL
SELECT 10,'October' as month UNION ALL
SELECT 11,'November' as month UNION ALL
SELECT 12,'December' as month
SELECT #years=COALESCE(#years+',','') +'['+ cast(years as varchar(4))+']',
#yearsColumns=COALESCE(#yearsColumns+',','') +'isnull(['+ cast(years as varchar(4))+'],0)
as ['+cast(years as varchar(4))+']'
from (select distinct YEAR(CurDate) years from EOD_Main
WHERE YEAR(CurDate)>=#StartYr AND YEAR(CurDate)<=#EndYr
) as x
SET #query = 'Select months,'+#yearsColumns+' from (
select distinct mID, YEAR(CurDate) years,[MONTH] months,
isnull(Warranty_Info,0) as Warranty_Info from EOD_Main
right join #tempMonths on datename(month,CurDate ) =[month]
) as xx
PIVOT
(
SUM(xx.Warranty_Info) FOR years IN ('+#years+')
)
as pvt ORDER BY mID'
PRINT #query
--EXEC(#query)
drop table #tempMonths
See this code
SELECT
#years = COALESCE(#years+',','') +'['+ cast(years as varchar(4))+']',
#yearsColumns = COALESCE(#yearsColumns+',','') +'isnull(['+ cast(years as varchar(4))+'], 0) as ['+cast(years as varchar(4))+']'
FROM
(SELECT distinct YEAR(CurDate) years
FROM EOD_Main
WHERE YEAR(CurDate) >= #StartYr AND YEAR(CurDate) <= #EndYr) as x
This inner most area
(SELECT distinct YEAR(CurDate) years
FROM EOD_Main
WHERE YEAR(CurDate) >= #StartYr AND YEAR(CurDate) <= #EndYr) as x**
I am not being able to order the year asc wise rather getting error.
In this area I want to generate year ascending wise.... so guide me what I can do. thanks
Order by is irrelevant in views. You will not automatically get teh records inteh right order. YOu need to havea an order by in all the sql code you want ordered.
Order by year(curDate)

sql : calculate the total birthday moth based on month

I want to code a query to calculate the total birthday moth based on month . Here is the sample data . Two person's bithday are April, 1980 .
How to write this query ?
John 02/21/1980
Peter 02/22/1980
Lucy 04/21/1980
------ result -----
01/1980 0
02/1980 2
03/1980 0
04/1980 1
05/1980 0
.....
You can loop for every months like this:
DECLARE #month INT
DECLARE #year INT
DECLARE #result TABLE (MonthYear varchar(7),BirthdaysCount INT)
SET #month = 1
SET #year = 1980
WHILE(#month < 13)
BEGIN
INSERT INTO #result
SELECT (CAST(#month as VARCHAR) + '/' + CAST(#year as VARCHAR)),
COUNT(*)
FROM test
WHERE MONTH(birth) = #month AND YEAR(birth) = #year
SET #month = #month + 1
END
select * from #result
See the fiddle: http://sqlfiddle.com/#!3/20692/2
In MySQL you would do this:
select concat(month(dob), '/', year(dob)) monthYear, count(*) cnt from t
group by monthYear
order by year(dob), month(dob)
However, in order to get the "missing dates" you'll have to generate data, because 01/1980 is not in any table, as far as I can see. Check this answer to see how.
how about this for sql-server
create table #temp
(
name varchar(50),
DOB datetime
)
insert into #temp values ('john', '2/21/1980')
insert into #temp values ('peter', '2/22/1980')
insert into #temp values ('lucy', '4/21/1980')
select convert(varchar(2), MONTH(DOB)) + '/' + Convert(varchar(4), YEAR(DOB)) as [MM/YYYY]
, count(*) as TotalCount
from #temp
group by convert(varchar(2), MONTH(DOB)) + '/' + Convert(varchar(4), YEAR(DOB))
drop table #temp
EDIT - This will get you all records for the dates included in the dates in the table. It will use the Min/Max Date in the table to get the date range, you then use this range to get the count of the birthdays in each month:
create table #temp
(
name varchar(50),
DOB datetime
)
insert into #temp values ('john', '2/21/1980')
insert into #temp values ('peter', '2/22/1980')
insert into #temp values ('lucy', '4/21/1980')
;with cte as
(
select min(DOB) as MinDate, max(DOB) as MaxDate
from #temp
union all
SELECT dateadd(mm, 1, t.MinDate), t.MaxDate
from cte t
where dateadd(mm, 1, t.MinDate) <= t.MaxDate
)
select convert(varchar(2), MONTH(c.MinDate)) + '/' + Convert(varchar(4), YEAR(c.MinDate))
, IsNull(t.TotalCount, 0) as TotalCount
from cte c
LEFT JOIN
(
SELECT convert(varchar(2), MONTH(DOB)) + '/' + Convert(varchar(4), YEAR(DOB)) as [MM/YYYY]
, count(*) as TotalCount
FROM #temp
group by convert(varchar(2), MONTH(DOB)) + '/' + Convert(varchar(4), YEAR(DOB))
) t
on convert(varchar(2), MONTH(C.MinDate)) + '/' + Convert(varchar(4), YEAR(C.MinDate))
= t.[MM/YYYY]
drop table #temp

Pivot In Values with dates?

At the end of my sql, I am using the following code. Is there any way of replacing the fixed strings [2011/07/14], [2011/07/16], etc, to GetDate() value?
PIVOT
(
count([AppointmentsBooked])
FOR [date] IN ([2011/07/14], [2011/07/16], [2011/07/17],[2011/07/18],[2011/07/21])
) as pivottable
Can you try to use BETWEEN and DATEADD in following manner:
DECLARE #dates TABLE(value DateTime)
INSERT INTO #dates VALUES
(GETDATE()),
('2011/07/9'),
('2011/07/17'),
('2011/07/18'),
('2011/07/21')
SELECT value FROM #dates
WHERE value BETWEEN GETDATE() AND DATEADD(day, 5, GETDATE())
You can create a string of all dates which is comma seperated with '[' and ']' before and after each date. assign this string to a string variable (#dates) and use the string spit method to split all dates inside the pivot query.
this question was posted about a year ago. i don't care. i have some code that might be exactly what the OP wanted.... i'm sure he'll never come back and chose an answer but still.... all i want to do is count the records by month with a pivot for a few tables and ultimately compare the number of records for each month for each table. however... in this code there is only one table (rt_taco_15m) but that doesn't matter. i just haven't written the rest to completely fit my needs. but i think it fits the needs of the OP or at least gets him on a good start.... if he truly has been waiting a year on this problem. lol.
if object_id('tempdb..#temp') is not null drop table #temp
if object_id('tempdb..#temp2') is not null drop table #temp2
if object_id('tempdb..#temp3') is not null drop table #temp3
declare #start_date as datetime
set #start_date = cast('1-1-2012' as datetime)
declare #end_date as datetime
set #end_date = cast('9-1-2012' as datetime)
;with cte as (
select #start_date as [start],
dateadd(month, 1, #start_date) as [end]
union all
select dateadd(month, 1, [start]) as [start],
dateadd(month, 1, dateadd(month, 1, [start])) as [end]
from cte
where dateadd(month, 1, [start]) <= #end_date
)
(select 'rt_taco_15m' as table_name,
convert(varchar(10), [start], 101) as [start],
convert(varchar(10), [end], 101) as [end],
datename(month, [start]) as month_name,
cast([start] as integer) as orderby,
count(taco.taco_record_id) as [range_count]
into #temp
from cte
left outer join rt_taco_15m as taco
on taco.period >= cte.[start] and
taco.period < cte.[end]
group by cte.[start], cte.[end])
select table_name as table_name,
convert(varchar(10), getdate(), 101) as [start],
convert(varchar(10), getdate(), 101) as [end],
'Total' as month_name,
cast(dateadd(month,2,#end_date) as integer) as orderby,
range_sum as [range_count]
into #temp2
from (select table_name, sum([range_count]) as range_sum
from #temp group by table_name) as summed_up
select *
into #temp3
from (select * from #temp
union all
select * from #temp2) as x
order by orderby
select * from #temp3
declare #cols nvarchar(2000)
select #cols = stuff(
(select '],[' + month_name
from #temp3
order by orderby
for xml path('') )
, 1, 2, '') + ']'
print #cols
if object_id('tempdb..#temp2') is not null drop table #temp2
declare #query varchar(max)
set #query = N'
select table_name, ' + #cols + N'
from (select table_name, month_name, range_count
from #temp3) p
pivot ( sum(range_count) for month_name in ( '+ #cols +' ) ) as pvt'
execute(#query