I'm trying to pivot data in my query (SQL Server 2008 R2) and I only need 2 columns pivoted but there may be up to 20 columns after the pivot. Here is my test data with up to 5 diagnosis codes:
pid DiagnosisCode
111 145.9
111 17.43
111 17.84
111 196.2
111 202.81
112 204.21
112 249.71
112 263.8
112 145.9
113 269.8
113 276.7
The output I'm trying to get looks like this:
pid | code1 | code2 | code3 | code4 | code5 | code6 | code... | code20
----------------------------------------------------------------------------
111 145.9 17.43 17.84 196.2 202.81 NULL NULL NULL
112 204.21 249.71 263.8 145.9 NULL NULL NULL NULL
113 269.8 276.7 NULL NULL NULL NULL NULL NULL
The code I have is :
select pid, DiagnosisCode
from
(select pid, DiagnosisCode, row_number() over(partition by pid order by pid)
as seq
from #temp
) as src
pivot
(min(DiagnosisCode)
for seq
in (DiagnosisCode)) pvt
For whatever reason, this function isn't clicking with me.I know that the MIN() aggregate function is required, but I don't need one in my output. I added the ROW_NUMBER() line so there would be a sequence field after reading one post, but I'm not sure why its needed. I've been reading all the other Pivot posts here and on other sites. I know this has been gone over many times on this site, but if you could help me understand what else I need in my query to get this to work I would be grateful.
You need to Fix your columns; the SQL Pivot table is different from Access, this is an example
declare #t as table (pid int , DiagnosisCode decimal(10,1))
insert #t select 111 , 145.9
insert #t select 111 , 17.43
insert #t select 111 , 17.84
insert #t select 111 , 196.2
insert #t select 111 , 202.81
insert #t select 112 , 204.21
insert #t select 112 , 249.71
insert #t select 112 , 263.8
insert #t select 112 , 145.9
insert #t select 113 , 269.8
insert #t select 113 , 276.7
select * from #t
select pid
,code1
,code2
,code3
,code4
,code5
,code6
,code7
,code8
,code9
,code10
,code11
,code12
,code13
,code14
,code15
,code16
,code17
,code18
,code19
,code20
from
(
select pid, DiagnosisCode, 'code' + cast(row_number() over(partition by pid order by pid) as varchar(2))
as seq
from #t
) as src
pivot
(min(DiagnosisCode)
for seq
in (
code1
,code2
,code3
,code4
,code5
,code6
,code7
,code8
,code9
,code10
,code11
,code12
,code13
,code14
,code15
,code16
,code17
,code18
,code19
,code20
)) pvt
pid code1 code2 code3 code4 code5 code6 code7 .... code20
---- ------ ------ ------- ------- ------ ------ ------ -------
111 145.9 17.4 17.8 196.2 202.8 NULL NULL NULL
112 204.2 249.7 263.8 145.9 NULL NULL NULL NULL
113 269.8 276.7 NULL NULL NULL NULL NULL NULL
Related
I have some data that looks like this:
Table1
Number TYPE Acct Total
------ --- --- ----
1X2 GGG 111 100
1X2 GGG 222 200
What I'm trying to do is PIVOT this data so that it looks like this:
Number Type 111 222
----- --- --- ---
1X2 GGG 100 200
Here's how I pivot:
Select * from Table1
PIVOT (MAX(Total)
FOR ACCT in ([111],[222],[333])
Now this works very well for Acct 111 and 222, but for 333 the Total = NULL. Thing is here, that I might sometimes have all three ACCTs, as in 111, 222, and 333. Other times as shown in the above example one of them might be missing.
Anywho, when I do my pivot the data looks like this:
Number Type 111 222 333
----- --- --- --- ---
1X2 GGG 100 200 NULL <-- I'm trying to set this to 0
As you can see, the Value for 333 is NULL - IS there anyway I can set this value to 0?
Two options. The first will use coalesce() to eliminate the null values. The second will create a a unique set of intersections via a CROSS JOIN and a UNION ALL (brute force)
Example
Declare #YourTable Table ([Number] varchar(50),[TYPE] varchar(50),[Acct] varchar(50),[Total] varchar(50))
Insert Into #YourTable Values
('1X2','GGG',111,100)
,('1X2','GGG',222,200)
Select Number
,Type
,[111] = coalesce( [111] ,0)
,[222] = coalesce( [222] ,0)
,[333] = coalesce( [333] ,0)
From #YourTable
PIVOT (MAX(Total)
FOR ACCT in ([111],[222],[333])) pvt
Second Option:
You may notice I supplied the Accts in the last CROSS JOIN because 333 was not in the scope of the sample data. If it will exist, you could use the Select Distinct Acct like we used in Cross Apply 1 and 2
Select *
From ( Select * from #YourTable
Union All
Select Number,Type,Acct,0
From ( Select distinct Number from #YourTable ) A
Cross Join (Select distinct Type from #YourTable) B
Cross Join (
Select * from (values ('111' )
,('222' )
,('333' )
)v(Acct)
) C
) src
PIVOT (MAX(Total)
FOR ACCT in ([111],[222],[333])) pvt
Both Results would be
I have table like below,
create table #temp
(
Name varchar(100),
Id int,
)
Insert into #temp values ('AAA',101)
Insert into #temp values ('AAA',102)
Insert into #temp values ('AAA',102)
Insert into #temp values ('AAA',103)
Insert into #temp values ('AAA',103)
Insert into #temp values ('BBB',201)
Insert into #temp values ('BBB',201)
Insert into #temp values ('BBB',202)
Insert into #temp values ('BBB',203)
Expected output:
Name Id Seq
-------------------
AAA 101 1
AAA 102 2
AAA 102 2
AAA 103 3
AAA 103 3
BBB 201 1
BBB 201 1
BBB 202 2
BBB 203 3
I want to generate sequence number based on name and Id. If Id is same, same sequence number needs to be assign.
Use DENSE_RANK:
SELECT
Name,
Id,
DENSE_RANK() OVER (PARTITION BY Name ORDER BY Id) Seq
FROM #temp;
Demo
I have this table.
ID Date Value
___ ____ _____
3241 9/17/12 5
3241 9/16/12 100
3241 9/15/12 20
4355 9/16/12 12
4355 9/15/12 132
4355 9/14/12 4
1001 NULL 89
1001 9/16/12 125
5555 NULL 89
1234 9/16/12 45
2236 9/15/12 128
2236 9/14/12 323
2002 9/17/12 45
I would like to select the maximum date grouped by id and including NULL as maximum value that should be in the result to get something like that.
ID Date Value
___ ____ _____
3241 9/17/12 5
4355 9/16/12 12
1001 9/16/12 125
5555 NULL 89
1234 9/16/12 45
2236 9/15/12 128
2002 9/17/12 45
I found a solution but that not include NULL as maximum value
the solution by #bluefeet
Return value at max date for a particular id
SELECT t1.id,
t2.mxdate,
t1.value
FROM yourtable t1
INNER JOIN
( SELECT max(date) mxdate,
id
FROM yourtable
GROUP BY id) t2 ON t1.id = t2.id
AND t1.date = t2.mxdate
I also search for a solution to see how can we select NULL maximum value in t-sql so i found this solution by #Damien_The_Unbeliever How can I include null values in a MIN or MAX?
SELECT recordid,
MIN(startdate),
CASE
WHEN MAX(CASE
WHEN enddate IS NULL THEN 1
ELSE 0
END) = 0 THEN MAX(enddate)
END
FROM tmp
GROUP BY recordid
But i m stuck i don't know how to merge between this two solution to get what i want.
PS: I m using SQL SERVER 2008
You can use this
SELECT
ID
,[Date]
,[Value]
FROM(
SELECT
*
, ROW_NUMBER() OVER(PARTITION BY ID ORDER BY ISNULL([Date],'9999-12-31') DESC) AS Row#
FROM yourtable
) A WHERE Row# = 1
This question already has an answer here:
Pivot without aggregate function in MSSQL 2008 R2
(1 answer)
Closed 6 years ago.
Hi I have the following table that I would like to use the pivot function on:
Id|Number| Code
1 | 34 |abc12345
1 | 23 |xqwe6758
2 | 37 |ghut564hg
3 | 456 |ghut8695
3 | 39 |ghtuj678
3 | 22 |fsdifje12
And I want it to be displayed horizontally as the following:
Id| Code1 | Code2 | Code3
1 | abc12345 | xqwe6758 | null
2 |ghut564hg | null | null
3 |ghut8695 | ghtuj678 | fsdifje12
SELECT Id
,[Code1]
,[Code2]
,[Code3]
FROM(SELECT Id,Code
FROM [TableName]
)d
pivot(
max(Id)
for Code in([Code1],[Code2],[Code3])
)as piv;
This throws an invalid column name error on the Id column. Could someone help identify the error ?
You can use pivot as below:
;with cte as
(
select
id, code,
RowN = Row_Number() over (partition by id order by code)
from
yourtable1
)
select *
from cte
pivot ( max(code) for RowN in([1], [2], [3])) p
For varying columns you can use stuff to create columns list and then use dynamic SQL to run with varying columns... But it is available in various examples in SO itself...
Added my output:
Try this
DECLARE #tbl TABLE(Id INT, Code VARCHAR(100));
INSERT INTO #tbl VALUES
(1,'abc12345')
,(1,'xqwe6758')
,(2,'ghut564hg')
,(3,'ghut8695')
,(3,'ghtuj678')
,(3,'fsdifje12');
SELECT p.*
FROM
(
SELECT Id
,'Code' + CAST(ROW_NUMBER() OVER(PARTITION BY Id ORDER BY Code) AS VARCHAR(10)) AS ColumnName
,Code
FROM #tbl
) AS t
PIVOT
(
MAX(Code) FOR ColumnName IN(Code1,Code2,Code3 /*add as many as you need*/)
) AS p
The result
Id Code1 Code2 Code3
1 abc12345 xqwe6758 NULL
2 ghut564hg NULL NULL
3 fsdifje12 ghtuj678 ghut8695
Good day, I'm trying to update my table. Because there was an error(s) in my website. first Please check my table. (Penilaian_Header)
IdPenilaian | KodePenilaian | Nip | PositionCode | Total
1613 ----- 1603405 P028 0
1618 ----- 1602999 P028 0
1641 PE0001568 603060 P040 35
1640 PE0001567 1411862 P007 35
as you can see. There are two rows that KodePenilaian empty. So is there any chance to fill it ? so the result will be like this.
IdPenilaian | KodePenilaian | Nip | PositionCode | Total
1613 PE0001570 1603405 P028 0
1618 PE0001569 1602999 P028 0
1641 PE0001568 603060 P040 35
1640 PE0001567 1411862 P007 35
This how i generate KodePenilaian
select case
when right(max(KodePenilaian),7) is null then 'PE0000001'
else ('PE' + RIGHT('0000000' + cast(right(max(KodePenilaian),7) + 1 as nvarchar),7))
end KodePenilaian from Penilaian_Header
and here is there result when i run it
KodePenilaian
PE0001569
Thanks, Sorry for my bad english.
Not really used to sql server 2008
Try something like this:
update Penilaian_Header pen
set pen.KodePenilaian =
(select case
when right(max(newKode.KodePenilaian),7) is null then 'PE0000001'
else ('PE' + RIGHT('0000000' + cast(right(max(newKode.KodePenilaian),7) + 1 as nvarchar),7))
end KodePenilaian
from Penilaian_Header newKode)
where pen.KodePenilain = NULL
if ----- is NULL in your table
You can try this way...
;WITH cte
AS (SELECT *,
MAX(CONVERT(int, REPLACE(KodePenilaian, 'PE000', ''))) OVER () AS MaxNum,
ROW_NUMBER() OVER (ORDER BY kodePenilaian) AS rn
FROM YourTable)
UPDATE cte SET KodePenilaian = concat('PE000', maxnum + rn)
WHERE KodePenilaian IS NULL
Your table
create table YourTable (
IdPenilaian int, KodePenilaian varchar(20), Nip int, PositionCode varchar(10), Total INT)
insert into YourTable
(IdPenilaian , KodePenilaian , Nip , PositionCode , Total) values
( 1613 , NULL , 1603405 ,'P028', 0 )
,( 1618 , NULL , 1602999 ,'P028', 0 )
,( 1641 , 'PE0001568' , 603060 ,'P040', 35 )
,( 1640 , 'PE0001567' , 1411862 ,'P007', 35 )