multiple column pivot in sql server - sql-server

I have some issue about how to make query result like
this is what i've tried,, but not exactly same like what i mean
CREATE TABLE #dta
(
Data [nvarchar](max),
Date [varchar] (12) ,
GR [int] ,
Refund [int] ,
Sales [int] ,
)
INSERT INTO #dta
SELECT 'asd',1,10,0,0 UNION ALL
SELECT 'asd',2,0,0,4 UNION ALL
SELECT 'asd',3,4,1,1 UNION ALL
SELECT 'qwe',1,2,0,0 UNION ALL
SELECT 'qwe',3,0,0,1 UNION ALL
SELECT 'zxc',1,0,0,5 UNION ALL
SELECT 'zxc',2,4,0,1 UNION ALL
SELECT 'zxc',3,0,1,5
--Only for sales
SELECT data, [1],[2],[3] FROM
(SELECT data, [date] , Sales FROM #dta )Tab1
PIVOT
(
SUM(Sales) FOR [date] IN ([1],[2],[3])) AS Tab2
ORDER BY Tab2.Data

You can use conditional aggregation and try something along this code:
SELECT t.[Data]
,MAX(CASE WHEN t.[Date]=1 THEN t.Sales END) AS [Sales_Date_1]
,MAX(CASE WHEN t.[Date]=1 THEN t.Refund END) AS [Refund_Date_1]
,MAX(CASE WHEN t.[Date]=1 THEN t.GR END) AS [GR_Date_1]
,MAX(CASE WHEN t.[Date]=2 THEN t.Sales END) AS [Sales_Date_2]
,MAX(CASE WHEN t.[Date]=2 THEN t.Refund END) AS [Refund_Date_2]
,MAX(CASE WHEN t.[Date]=2 THEN t.GR END) AS [GR_Date_2]
,MAX(CASE WHEN t.[Date]=3 THEN t.Sales END) AS [Sales_Date_3]
,MAX(CASE WHEN t.[Date]=3 THEN t.Refund END) AS [Refund_Date_3]
,MAX(CASE WHEN t.[Date]=3 THEN t.GR END) AS [GR_Date_3]
FROM #dta t
GROUP BY t.[Data];
If the count of t.[Date] (1 to 3 in your example data) is not limited to a known maximum, you'd have to create the statement dyanmically.
If your t.[Date] column is a date value actually and you want your output columns named after some date values (unpredictable column alias) within your set, you must create this dynamically too.

Related

TSQL results in specific number of columns

I'm trying to create a query that will distribute the row results in specific number of columns (ex. 4). See below screenshot.
It is presentation matter and it should be handled on application level.
But if you insist:
SELECT column1 = MIN(CASE WHEN grp=1 THEN PartNumber+CHAR(13)+SerialNumber END)
,column2 = MIN(CASE WHEN grp=2 THEN PartNumber+CHAR(13)+SerialNumber END)
,column3 = MIN(CASE WHEN grp=3 THEN PartNumber+CHAR(13)+SerialNumber END)
,column4 = MIN(CASE WHEN grp=4 THEN PartNumber+CHAR(13)+SerialNumber END)
FROM (SELECT *,ROW_NUMBER() OVER(PARTITION BY rn ORDER BY rn) AS grp
FROM (SELECT *,(ROW_NUMBER() OVER(ORDER BY 1/0)-1)/4 AS rn FROM tab)s)sub
GROUP BY rn;
DBFiddle Demo

How to pivot table from multiple column to multiple rows

CodeDt CodeHeader Item Qty Type Remark Attachment
LK4-033502 RK-K-LK4-032438 IA01001023 2.00 TPR002 2 1.jpeg
LK4-033502RK RK-K-LK4-032438 IA01001023RK 2.00 NULL IA01001023 NULL
Above is my data from Sql server table (using 2008 R2). I want to make it one row only. Here is my expected result:
CodeDt CodeHeader Item NewItem Qty
LK4-033502 RK-K-LK4-032438 IA01001023 IA01001023RK 2.00
How can I achieve that? Here is the relation:
Row 1 Item = Row 2 Remark,
Row 1 Code DT = Row 2 CodeDt+'RK'
There are several solutions
1) Using JOIN. It assumes that Type field is null for rows with CodeDt+'RK'
select
a.CodeDt, a.CodeHeader, a.Item, b.Item, a.Qty
from
myTable a
join myTable b on a.Item = b.Remark
where
a.Type is not null
2) Conditional aggregation
select
max(case when rn = 1 then CodeDt end)
, CodeHeader
, max(case when rn = 1 then Item end)
, max(case when rn = 2 then Item end)
, max(case when rn = 1 then Qty end)
from (
select
*, rn = row_number() over (partition by CodeHeader order by CodeDt)
from
myTable
) t
group by CodeHeader

Create a grand total row in sql server

I'm writing a query where in there should be a total row at the end of the table that gives the sum of the closed , open, reassigned columns.
I'm able to make a pivot, but unable to know how to place a row in the end. I've searched online but mostly found solutions for creating a column and a row or just column. I'm into Dev, dunno much about the databases. below is my pivot. please let me know how can i do this.
select *
from
(
select [case owner] as AGENT, [final status]
from StatusTable
) src
pivot
(
count([final status])
for [final status] in ([CLOSED], [OPEN], [REASSIGNED])
) piv
The current output is as below image
And here I want an extra row as shown below.
TOTAL | 2 | 8 | 2
You can use UNION ALL to concat rowsets with identical columns:
with ctePivot as (
select *
from
(
select [case owner] as AGENT, [final status]
from StatusTable
) src
pivot
(
count([final status])
for [final status] in ([CLOSED], [OPEN], [REASSIGNED])
) piv
)
select * from ctePivot
union all
select 'TOTAL', sum([CLOSED]), sum([OPEN]), sum([REASSIGNED]) from ctePivot
Or the simpler variant with only a GROUP BY ROLLUP:
select ISNULL([case owner], 'TOTAL') as AGENT,
SUM(CASE WHEN [final status]='CLOSED' THEN 1 ELSE 0 END) [CLOSED],
SUM(CASE WHEN [final status]='OPEN' THEN 1 ELSE 0 END) [OPEN],
SUM(CASE WHEN [final status]='REASSIGNED' THEN 1 ELSE 0 END) [REASSIGNED]
from StatusTable
GROUP BY ROLLUP ([case owner]);
Assuming agent is a key field, you can aggregate on that and use GROUP BY ROLLUP():
select coalesce(piv.agent,'Grand Total') agent
,sum(piv.closed) closed
,sum(piv.open) open
,sum(piv.reassigned) reassigned
from
(
select [case owner] as AGENT, [final status]
from StatusTable
) src
pivot
(
count([final status])
for [final status] in ([CLOSED], [OPEN], [REASSIGNED])
) piv
group by rollup(piv.agent)
If you write your query as a group by instead of a pivot, you can use with rollup to get your total row. E.g.:
select
[AGENT] = case when grouping([case owner])=1 then 'TOTAL' else [case owner] end,
[CLOSED] = sum(case when [final status] = 'CLOSED' then 1 else 0 end),
[OPEN] = sum(case when [final status] = 'OPEN' then 1 else 0 end),
[REASSIGNED] = sum(case when [final status] = 'REASSIGNED' then 1 else 0 end)
from StatusTable
group by [case owner]
with rollup
http://sqlfiddle.com/#!3/e0bb5/8/0

How to show data as per my requirement in sql server 2005

here is my table structure
create table DailyFinishJobsHistory
(
RowID INT NOT NULL IDENTITY (1, 1),
[Job Type] Varchar(16) NOT NULL,
[No of Jobs] INT NOT NULL DEFAULT ((0)),
[Turnaround Time] DECIMAL(10,2) NOT NULL DEFAULT ((0)),
[One Day Per] DECIMAL(8,2),
CreatedDate datetime DEFAULT (GetDate())
)
this way data is stored in table screen shot
now i have to show the data this way & order by date asc and where clause will be there where i need to specify two date.
date OUR_No of jobs OUR_Turnaround_time OUR_One day per Salesnew_ of jobs Salesnew_no of jobs Salesnew_turnaround_time this way i need to show...
i guess i need to use pivot but whatever i tried did not work. so any help will be appreciated. thanks
Your question and requirements are not very clear but I am going to take a guess that you want the following:
select
convert(varchar(10), createddate, 120) date,
sum(case when [job type] = 'OUR' then [No of Jobs] else 0 end) OurNoOfJobs,
sum(case when [job type] = 'OUR' then [Turnaround Time] else 0 end) OurTurnaroundTime,
sum(case when [job type] = 'OUR' then [One Day Per] else 0 end) OurOneDayPer,
sum(case when [job type] = 'SALESNEW' then [No of Jobs] else 0 end) SalesNewNoOfJobs,
sum(case when [job type] = 'SALESNEW' then [Turnaround Time] else 0 end) SalesNewTurnaroundTime,
sum(case when [job type] = 'SALESNEW' then [One Day Per] else 0 end) SalesNewOneDayPer
from DailyFinishJobsHistory
group by convert(varchar(10), createddate, 120);
See SQL Fiddle with Demo.
This uses an aggregate function and a CASE expression to convert and your rows of data into columns using the sum function to aggregate the values the in columns that you want.

Help with finding the difference (delta) from a value returned from the last two records

I'm using MS SQL 2005 and I have created a CTE query to return values from the last two records. I then use this to find the delta of two figures returned. I have a working query of sorts but
I'm having problems getting anything other than the delta figure.
here is my query:
;with data as(
SELECT
NetObjectID,
RawStatus,
RowID,
rn
from(
SELECT
CustomPollerAssignmentID AS NetObjectID,
RawStatus,
RowID,
row_number() over(order by DateTime desc)as rn
FROM CustomPollerStatistics_Detail
WHERE
(CustomPollerAssignmentID='a87f531d-4842-4bb3-9d68-7fd118004356')
) x where rn<=2
)
SELECT
case when
max(case rn when 1 then RawStatus end) > max(case rn when 2 then RawStatus end)
then
max(case rn when 1 then RawStatus end) - max(case rn when 2 then RawStatus end)
else
max(case rn when 2 then RawStatus end) - max(case rn when 1 then RawStatus end)
end as Delta
from data having
(SELECT
case when
max(case rn when 1 then RawStatus end) > max(case rn when 2 then RawStatus end)
then
max(case rn when 1 then RawStatus end) - max(case rn when 2 then RawStatus end)
else
max(case rn when 2 then RawStatus end) - max(case rn when 1 then RawStatus end)
end
from data) >= 1
What I'm after is to get the Delta & NetObjectID returned. Each time I try, I get errors.
data.NetObjectID is invalid in the select list because it is not contained in either an aggregate function or the group by clause.
If I try adding group by etc.. to the end of the query I get further error complaining about the word 'group'.
I'm relatively new to SQL and I am picking things up as I go. Any help would be gratefully received.
see if something like this will work.
;with data as
(
SELECT
NetObjectID,
RawStatus,
RowID,
rn
from
(
SELECT
CustomPollerAssignmentID AS NetObjectID,
RawStatus,
RowID,
row_number() over(order by DateTime desc)as rn
FROM CustomPollerStatistics_Detail
WHERE
(
CustomPollerAssignmentID='a87f531d-4842-4bb3-9d68-7fd118004356'
)
) x
where rn<=2
)
select
NetObjectID,
max(RawStatus)-min(RawStatus) as Delta
from data
group by NetObjectID
Sorry, I'm very new here and I'm unsure of CTE queries, however it looks like after you define Data, you are selecting case ... as Delta FROM.... Meaning you only have Delta in your select statement. Again, sorry if I'm way off base.

Resources