Rows to columns not working well - sql

I am using SQL Server 2014 and what I would like to do is from the following result:
Answer QuestionID
Low Effort 1
Satisfied 2
Yes 3
Not Applicable 4
Likely 5
Very patient and an excellent help. The TV is working fine now thanks again Ria
Peter 6
Excellent 8
produce something like:
1 |2 |3 |4 .... |8
Low Effort |Satisfied |Yes |Not Applicable.... |Excellent
I am using this query but is not working properly:
select
'1', '2', '3', '4', '5', '6', '7', '8', '9'
from
(select
Answer, QuestionID
from
[dbo].[SurveyDataDetail]) d
pivot
(max(Answer)
for QuestionID in (1, 2, 3, 4, 5, 6, 7, 8, 9)
) piv;
Any comments?

Don't use single quotes. Use escape characters:
select [1], [2], [3], [4], [5], [6], [7], [8], [9]
Single quotes should only be used for string and constants.
The full query would be:
select [1], [2], [3], [4], [5], [6], [7], [8], [9]
from (select Answer, QuestionID
from [dbo].[SurveyDataDetail]
) d
pivot (
max(Answer)
for QuestionID in ([1], [2], [3], [4], [5], [6], [7], [8], [9])
) piv;

Related

rename columns in SQL Query transpose

I have a SQL query than transpose rows by columns but i dont know how to rename the columns.
select *
from
(select CustomerID, FiscalPeriod, SaleAmtLocalCurr
from PerfTrk.dbo.IRIS_SaleFact
where CountryCode = '00001'
and DivisionCode = 'INS'
and SaleAmtLocalCurr > 0
and datefromparts(FiscalYear, FiscalPeriod, 1) between datefromparts(2019,9, 1) and datefromparts(2020,8, 31)) d
pivot
(sum(SaleAmtLocalCurr) for FiscalPeriod in ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12])
) piv;
The result is
CustomerID 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
I want to rename the columns with the names of months
Thanks
CASE is always an option
select
*
from
(select
CustomerID,
(CASE
WHEN FiscalPeriod = 1 THEN 'JAN'
WHEN FiscalPeriod = 2 THEN 'FEB'
WHEN FiscalPeriod = 3 THEN 'MAR'
WHEN FiscalPeriod = 4 THEN 'APR'
WHEN FiscalPeriod = 5 THEN 'MAY'
WHEN FiscalPeriod = 6 THEN 'JUN'
WHEN FiscalPeriod = 7 THEN 'JUL'
WHEN FiscalPeriod = 8 THEN 'AUG'
WHEN FiscalPeriod = 9 THEN 'SEP'
WHEN FiscalPeriod = 10 THEN 'OCT'
WHEN FiscalPeriod = 11 THEN 'NOV'
WHEN FiscalPeriod = 12 THEN 'DEC'
END) AS 'Month',
SaleAmtLocalCurr
from
PerfTrk.dbo.IRIS_SaleFact
where
CountryCode = '00001'
and DivisionCode = 'INS'
and SaleAmtLocalCurr > 0
and datefromparts(FiscalYear, FiscalPeriod, 1)
between datefromparts(2019,9, 1) and datefromparts(2020,8, 31)) d
pivot
(sum(SaleAmtLocalCurr) for FiscalPeriod in ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12])
) piv;

How do I combine two columns into single column in static / dynamic pivot query using SQL Server

I have a schema like this
demo(month_year(navarchar), datecount(int), destination(nvarchar), type(nvarchar)).
In output i want to transform the rows to columns with concatenate columns.
datecount | Month_year | destination type
-------------------------+---------------+-------------------
07 | March - 18 | ABC No
23 | August - 2018 | ABC No
29 | August - 2018 | XYZ Sold Out
04 | July - 2018 | PQR Sold Out
10 | July - 2018 | XYZ No
25 | July - 2018 | ABC Sold Out
In the output i want,
Month_Year 1 2 3 ...
July - 2018 04(Sold Out-PQR) 10(No-XYZ) 25(Sold Out-ABC)
August - 2018 23(No-ABC) 29(Sold Out-XYZ)
I have tried more using the PIVOTE function. Facing the problem to display combination of datecount with destination and type as per above expected output. But could not get the solution. Please help me.
Just concatenate the values before pivoting.
;WITH ToPivot AS
(
SELECT
D.month_year,
ConcatenatedValues = CONVERT(VARCHAR(10), D.datecount) + '(' + D.type + '-' + D.destination + ')',
NumberToPivot = ROW_NUMBER() OVER (PARTITION BY D.month_year ORDER BY D.datecount ASC)
FROM
Demo AS D
)
SELECT
P.*
FROM
ToPivot AS T
PIVOT (
MAX(T.ConcatenatedValues)
FOR T.NumberToPivot IN (
[1], [2], [3], [4], [5], [6], [7], [8], [9], [10],
[11], [12], [13], [14], [15], [16], [17], [18], [19],
[20], [21], [22], [23], [24], [25], [26], [27], [28],
[29], [30], [31])
) AS P

Case Statement Null Issues

I always get null value issues whenever I try to use a case statement on a data from the same column.
Data in database:
Month Sum
Jan 1000
Feb 2000
Mar 3000
Desired Result:
Jan Feb Mar
1000 2000 3000
When I tried using case statement I was running into null issue and was getting results like below:
Jan Feb Mar
1000 Null Null
Null 2000 Null
Null Null 3000
Here is the code that creates null value issue.
select AccountID,
sum(Case when DATEPART(month,EndDateTime) = 10 then Budget End) period1,
sum(case when DATEPART(month,EndDateTime) = 11 then Budget end) period2,
sum(case when DATEPART(month,EndDateTime) = 12 then Budget End) period3,
Description,
from Budget
where DATEPART(month,EndDateTime) in ('10','11','12')
group by AccountID,Description,EndDateTime
order by AccountID,Description,EndDateTime;
Using Pivot function I was able to generate the desired result.
SELECT
AccountID,
[1] AS Jan,
[2] AS Feb,
[3] AS Mar,
[4] AS Apr,
[5] AS May,
[6] AS Jun,
[7] AS Jul,
[8] AS Aug,
[9] AS Sep,
[10] AS Oct,
[11] AS Nov,
[12] AS Dec
FROM
(Select
AccountID,
Budget,
MONTH(EndDateTime) as TMonth
from
dbo.Budget) source
PIVOT
(
SUM(Budget)
FOR TMonth
IN ( [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12] )
) AS pvtMonth
The current issue I am now having is that I need to add one more sum function Sum(BudgetNet). Any suggestions?
Thanks.
For the type of result that you are wanting, it looks like you should be using PIVOT instead of CASE.

SQL To Calculate "To Date" Values With Month Columns

SQL Afficianados,
There has got to be a better way than the road I am going down...
SQL Fiddle HERE
Using SQL Server 2008. In short, I have a table with months as columns. i.e.:
CREATE TABLE MyData (MyID VARCHAR(10),
JAN MONEY, FEB MONEY, MAR MONEY, APR MONEY, MAY MONEY, JUN MONEY,
JUL MONEY, AUG MONEY, SEP MONEY, OCT MONEY, NOV MONEY, DEC MONEY);
Given a month value of N (as integer, where 1 = JAN and 12 = DEC), I want to calculate a "To Date" value from the first month to the Nth month.
So, given this simple data:
INSERT INTO MyData (MyID, JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC)
SELECT 'Rec1', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
UNION ALL SELECT 'Rec2', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
UNION ALL SELECT 'Rec3', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
;
I want to pass in any month value and add up the proper month columns. Given the sample data above, here is a chart of expected results based on the value of the month passed in...
Month Value | Expected Result |
------------+------------------
1 | 3
2 | 9
3 | 18
4 | 30
5 | 45
6 | 63
7 | 84
8 | 108
9 | 135
10 | 165
11 | 198
12 | 234
I know I could do this with a CASE statement like this:
DECLARE #v_Month INT = 2
SELECT CASE
WHEN #v_Month = 1 THEN SUM(JAN)
WHEN #v_Month = 2 THEN SUM(JAN) + SUM(FEB)
WHEN #v_Month = 2 THEN SUM(JAN) + SUM(FEB) + SUM(MAR)
--You get the idea. The pattern would continue for the rest of the months.
ELSE 0
END AS ToDateSum
FROM MyData
But is there a better way? Teach me, oh great ones of SQL Server.
You can use unpivot to change the data to a more amenable shape. It might make more sense to store it this way in the first place.
declare #v_Month int = 2;
with u as (
select
myid, [month], amount
from (
select
myid, jan [1], feb [2], mar [3], apr [4], may [5], jun [6],
jul [7], aug [8], sep [9], oct [10], nov [11], dec [12]
from
MyData
) p
unpivot (
amount for [month] in ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12])
) u
) select
sum(amount)
from
u
where
[month] <= #v_Month;
Example SQLFiddle
You can simplify this a bit, if you want to keep the data in the same structure:
select
sum(amount)
from (
select
myid, jan [1], feb [2], mar [3], apr [4], may [5], jun [6],
jul [7], aug [8], sep [9], oct [10], nov [11], dec [12]
from
MyData
) p
unpivot (
amount for [month] in ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12])
) u
where
[month] <= #v_Month;
Something like this will work:
declare #MyDesiredMonth int = 3
with normalized_view as
(
select MyId , Month = 1 , Value = Jan from MyData
UNION ALL select MyId , Month = 2 , Value = Feb from MyData
UNION ALL ...
UNION ALL select MyId , Month = 11 , Value = Nov from MyData
UNION ALL select MyId , Month = 12 , Value = Dec from MyData
)
select MonthlyTotal = sum(Value)
from normalized_view t
where t.Month = #myDesiredMonth
Alternatively, something like this:
declare #MyDesiredMonth int = 3
select MonthlyTotal = sum( case #MyDesiredMonth
when 1 then t.Jan
when 2 then t.Feb
...
when 11 then t.Nov
when 12 then t.Dec
end
)
from MyTable t
Either one should work with the execution plan likely winding up similar.

Table Design for User Selectable Schedule and Select Using PIVOT

I am creating a scheduling application that allows employees to input their desired schedule which is stored in a table. The current design I'm looking at is below using SQL 2008 R2.
CREATE TABLE [dbo].[Schedule] (
[EmpNum] [varchar](10) NOT NULL,
[Start] [datetime] NOT NULL,
[Length] [decimal](18, 2) NOT NULL,
[Reason] [varchar](1) NOT NULL,
CONSTRAINT [PK_Schedule] PRIMARY KEY CLUSTERED
(
[EmpNum] ASC,
[Start] ASC
)
)
A few things to note
A user may have entered no schedule for a specific date range and still want to see their name listed but with no schedule
A user may select nothing for a day in a week, but select something for other days
Start is the beginning of the shift
Length is the number of hours a shift is, may vary WILDLY from day to day and person to person
The Reason column is for what has been selected by the user (W - Work, P - PTO, etc)
Here is sample data
EmpNum Start Length Reason
---------- ----------------------- --------------------------------------- ------
000001 2012-08-02 09:00:00.000 12.00 W
000001 2012-08-04 08:00:00.000 9.50 P
000002 2012-08-02 08:30:00.000 10.00 W
000002 2012-08-03 19:00:00.000 12.00 W
000003 2012-08-03 08:00:00.000 8.00 P
The output I desire is something like this
EmpNum [0] [1] [2] [3] [4] [5] [6]
---------- ------ ------ ------ ------ ------ ------ ------
000001 NULL NULL NULL NULL W NULL P
000002 NULL NULL NULL NULL W W NULL
000003 NULL NULL NULL NULL NULL P NULL
I've never used a PIVOT query before since we just upgraded from SQL 2000, so bear with me. I've constructed the below query which fails with the below error and I'm stuck.
Msg 102, Level 15, State 1, Line 14
Incorrect syntax near '('.
Query
declare #FirstDayOfWeek date
set #FirstDayOfWeek = '7/29/2012'
select EmpNum,
#FirstDayOfWeek [0],
dateadd(day, 1, #FirstDayOfWeek) [1],
dateadd(day, 2, #FirstDayOfWeek) [2],
dateadd(day, 3, #FirstDayOfWeek) [3],
dateadd(day, 4, #FirstDayOfWeek) [4],
dateadd(day, 5, #FirstDayOfWeek) [5],
dateadd(day, 6, #FirstDayOfWeek) [6]
from Schedule
pivot (
max(Reason)
for Start in ([0], [1], [2], [3], [4], [5], [6])
) as Pvt
Any thoughts on how to best implement this or how badly wrong I am here?
It looks like you are trying to PIVOT your data based on the Day of the Week 1-7. I suggest a slight change to this to get it to work:
SELECT *
FROM
(
select EmpNum,
reason,
datepart(dw, start) as DyOfWk
from #Schedule
) s
pivot (
max(Reason)
for dyofwk in ([1], [2], [3], [4], [5], [6], [7])
) as Pvt
See SQL Fiddle with Demo
Results: