Split with '#' in SQL Server [duplicate] - sql-server

This question already has answers here:
Split and get second row as value [duplicate]
(3 answers)
Closed 4 years ago.
Current Result:
Data
-----
1#2#3#4#5#6
Expected Result:
Data1 Data2 Data3 Data4 Data5 Data6
----------------------------------------
1 2 3 4 5 6
Tried with SUBSTRING(), LEFT(), CHARINDEX() but didn't help.
Can anybody please tell, what I'm missing?

Try:
DECLARE #Var NVARCHAR(MAX)
SET #Var ='1#2#3#4#5#6'
DECLARE #XML AS XML
DECLARE #Delimiter AS CHAR(1) ='#'
SET #XML = CAST(('<X>'+REPLACE(#Var,#Delimiter ,'</X><X>')+'</X>') AS XML)
DECLARE #temp TABLE (ID INT,name NVARCHAR(MAX))
INSERT INTO #temp
SELECT N.value('.', 'INT') AS ID, 'data' + CONVERT(Nvarchar,N.value('.', 'INT')) as name
FROM #XML.nodes('X') AS T(N)
SELECT *
FROM #temp
PIVOT
(
MAX(id)
FOR name IN ([data1],[data2],[data3],[data4],[data5],[data6])
) PIV;
Result:
data1 data2 data3 data4 data5 data6
1 2 3 4 5 6
With Dynamic SQL:
SELECT *
INTO ##temp
FROM #temp
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
SELECT #cols = STUFF((SELECT ',' + QUOTENAME(name)
from #temp
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET #query = N'SELECT *
FROM
##temp
PIVOT
(
MAX(id)
FOR name IN (' + #cols + N')
) PIV'
EXEC(#query)
DROP TABLE ##temp

Try this :
SELECT value FROM STRING_SPLIT('1#2#3#4#5#6', '#');
the result here

Related

SQL Server : pivot table from Dynamic SQL first time with pivot

I am trying to create a pivot table that lists the time frames (responseText) as columns with the average answer for each one under that particular column based on the question asked. I am trying to do this with a PIVOT function - to no avail.
I have the following table
I first create a temp table and populate it with values from a stored procedure, then I am building a dynamic query
CREATE TABLE #Data
(
QuestionText varchar(400),
ResponseText varchar(200),
AverageAnswer float
)
INSERT INTO #Data
EXECUTE AverageDemographicGroupAnswer #GroupID, #Survey, #Demographic
--SELECT * FROM #Data
DECLARE #PivotQuery NVARCHAR(MAX)
DECLARE #Cols varchar(max)
SET #Cols = STUFF((SELECT distinct ',' + QUOTENAME(ResponseText,'[]') FROM dbo.SurveyResponses WHERE QuestionID = #Demographic FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'')
--SELECT #Cols
SET #PivotQuery = 'SELECT QuestionText, '+ #Cols +' FROM
(
SELECT QuestionText, ResponseText, AverageAnswer FROM #Data
)x
PIVOT
( AverageAnswer FOR ResponseText in (' + #Cols + ')
)p'
--select #PivotQuery
EXECUTE(#PivotQuery)
DROP TABLE #Data
Which produces this query
SELECT QuestionText, [At least 1 year but less than 3 years],[At least 3 years but less than 5 years],[Less than 1 year],[More than 5 years] FROM (SELECT QuestionText, AverageAnswer, ResponseText FROM #Data) AS SourceTable
PIVOT( AverageAnswer FOR ResponseText in ([At least 1 year but less than 3 years],[At least 3 years but less than 5 years],[Less than 1 year],[More than 5 years])) AS PivotTable
but it is returning this error
Incorrect syntax near the keyword 'FOR'.
This is my first time creating a pivot and I am not sure what is wrong

How to generate report using PIVOT based on date

I have two tables MasterTableTest8 and HistoricDatatest8.
create table MasterTableTest8
(ID int primary key, Name varchar(10))
insert into MasterTableTest8 values (1,'ATS')
insert into MasterTableTest8 values (2,'BTS')
CREATE TABLE HistoricDatatest8
(
ID int FOREIGN KEY REFERENCES MasterTableTest8(ID),
Name varchar(100),
ShortName varchar(10),
Reason varchar(10),
Importance varchar(10),
Noofissues int,
inserteddate datetime
)
insert into HistoricDatatest8 values (1,'ATS','S', 'Other','High',26,getdate()-7)
insert into HistoricDatatest8 values (1,'ATS','S', 'Other','High',8,getdate()+7)
insert into HistoricDatatest8 values (1,'ATS','S', 'Other','High',80,getdate())
insert into HistoricDatatest8 values (2,'BTS','S1', 'Other','LOW',26,getdate()-7)
insert into HistoricDatatest8 values (2,'BTS','S1', 'Other','LOW',8,getdate()+7)
insert into HistoricDatatest8 values (2,'BTS','S1', 'Other','LOW',80,getdate())
--Created and inserted two tables.
select
N.ID,
N.Name,
ShortName,
Reason,
Importance,
Noofissues,
inserteddate
INTO #TABLE
FROM HistoricDatatest8 N
JOIN MasterTableTest S ON N.ID=S.ID
--Inserting the required data in the Hash table.
--drop table #table
DECLARE #cols NVARCHAR (MAX)
SELECT #cols = COALESCE (#cols + ',[' + CONVERT(NVARCHAR, [inserteddate], 106) + ']',
'[' + CONVERT(NVARCHAR, [inserteddate], 106) + ']')
FROM (SELECT DISTINCT [inserteddate] FROM #TABLE) PV
ORDER BY [inserteddate]
DECLARE #query NVARCHAR(MAX)
SET #query = '
SELECT * FROM
(
SELECT * FROM #TABLE
) x
PIVOT
(
count(Noofissues)
FOR [inserteddate] IN (' + #cols + ')
) p'
EXEC SP_EXECUTESQL #query
Current Result
Expected Result:
What is your expected result? Your current display shows the same current and expected result.
Are you expecting:
Date | Name | ShortName | Reason | Importance | Number of Issues|
05-Jul-16 | ATS | S| Other| High|26
12-Jul-16|BTS |S1| Other | LOW|80
After lots of R & D i got this result, might be useful to some others. if any optimized answer will be appreciated.
select * from HistoricDatatest80 order by ID
select N.ID,N.Name,ShortName,Reason,Importance,Noofissues,inserteddate INTO #TABLE FROM HistoricDatatest80 N JOIN MasterTableTest80 S ON N.ID=S.ID
--drop table #table
DECLARE #cols NVARCHAR (MAX)
SELECT #cols = COALESCE (#cols +',','')+ '['+DATEValue+']'
FROM (SELECT DISTINCT (CONVERT(NVARCHAR, [inserteddate], 106)) AS DATEValue FROM HistoricDatatest80) PV
ORDER BY DATEValue
print #cols
DECLARE #query NVARCHAR(MAX)
SET #query = '
SELECT * FROM
(
SELECT ShortName,Reason,Importance,Noofissues,(CONVERT(NVARCHAR, [inserteddate], 106)) AS DATEValue FROM #TABLE
) x
PIVOT
(
sum(Noofissues)
FOR [DATEValue] IN (' + #cols + ')
) p'
EXEC SP_EXECUTESQL #query
drop table #table

sql server - transforming data with dynamic pivot [duplicate]

This question already has answers here:
SQL Server dynamic PIVOT query?
(9 answers)
Closed 7 years ago.
I need to dynamically transform data in table #table from this format:
spot_id name pct
------- ---- ---
1 A 2
1 B 8
1 C 6
2 A 4
2 B 5
3 A 5
3 D 1
3 E 4
to:
spot_id A B C D E
------- --- --- --- --- ---
1 2 5 6 0 0
2 4 5 0 0 0
3 5 0 0 1 4
The thing is that I don't know in advance what the values of column "name" are or how many of them there are, so I think that I have to use some kind of dynamic SQL pivoting
Just figured out how to solve the problem:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT ',' + QUOTENAME(name)
from (SELECT DISTINCT name FROM #table) T
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = N'SELECT spot_id,' + #cols + N' from
(
select spot_id, name, pct
from #table
) as x
pivot
(
max(pct)
for name in (' + #cols + N')
) as p '
exec sp_executesql #query;
If there more elegant way to do the same?
declare #t table (Spot int,name varchar(1),pct int)
insert into #t(Spot,name,pct)values(1,'A',2),(1,'B',8),(1,'C',6),(2,'A',4),(2,'B',5),(3,'A',5),(3,'D',1),(3,'E',4)
select Spot,ISNULL([A],0)[A],ISNULL([B],0)[B],ISNULL([C],0)[C],ISNULL([D],0)[D],ISNULL([E],0)[E] from (Select Spot,PCT,Name from #t)T
PIVOT(MAX(PCT) FOR Name IN ([A],[B],[C],[D],[E]))P
select Spot,ISNULL(MAX(CASE WHEN name = 'A' THEN pct END),0)A,ISNULL(MAX(CASE WHEN name = 'B' THEN pct END),0)B ,
ISNULL(MAX(CASE WHEN name = 'C' THEN pct END),0)C ,
ISNULL(MAX(CASE WHEN name = 'D' THEN pct END),0)D ,ISNULL(MAX(CASE WHEN name = 'E' THEN pct END),0)E from #t
GROUP BY Spot
Using Dynamic Query :
if object_id('tempdb..#t') is not null
drop table #t
CREATE table #t(Spot int,name varchar(1),pct int)
insert into #t(Spot,name,pct)values(1,'A',2),(1,'B',8),(1,'C',6),(2,'A',4),(2,'B',5),(3,'A',5),(3,'D',1),(3,'E',4)
DECLARE #statement NVARCHAR(max)
,#columns NVARCHAR(max)
SELECT #columns = ISNULL(#columns + ', ', '') + N'[' + tbl.name + ']'
FROM (
SELECT DISTINCT name
FROM #t
) AS tbl
SELECT #statement = ' select Spot,ISNULL([A],0)[A],ISNULL([B],0)[B],ISNULL([C],0)[C],ISNULL([D],0)[D],ISNULL([E],0)[E] from (Select Spot,PCT,Name from #t)T
PIVOT(MAX(PCT) FOR Name IN (' + #columns + ')) as pvt'
EXEC sp_executesql #statement = #statement

T-SQL query on dynamic field with pivot

i have 3 table PhoneBook, DynamicField, PhoneBook_DynamicField_Rel
PhoneBook :
|---ID----|---Name----|
1 Reza
2 Ali
DynamicField :
|---ID----|--Caption--|
1 Job
2 Level
PhoneBook_DynamicField_Rel:
|---ID----|--PhoneBookID--|--DynamicFieldID--|---Value---|
1 1 1 Emp
2 1 2 1
3 2 1 SomeJob
i want execute query with this result :
|--PhoneBookID--|--Name--|--Job--|--Level--|
1 Reza Emp 1
2 Ali SomeJob NULL
Maybe something like this:
Test data:
CREATE TABLE #PhoneBook(ID INT,Name VARCHAR(100))
INSERT INTO #PhoneBook VALUES(1,'Reza'),(2,'Ali')
CREATE TABLE #DynamicField(ID INT,Caption VARCHAR(100))
INSERT INTO #DynamicField VALUES(1,'Job'),(2,'Level')
CREATE TABLE #PhoneBook_DynamicField_Rel(ID INT,PhoneBookID INT,
DynamicFieldID INT,Value VARCHAR(100))
INSERT INTO #PhoneBook_DynamicField_Rel
VALUES(1,1,1,'Emp'),(2,1,2,'1'),(3,2,1,'SomeJob')
Getting the colums
DECLARE #cols VARCHAR(MAX)
SELECT #cols=STUFF
(
(
SELECT
',' +QUOTENAME(tbl.Caption)
FROM
#DynamicField AS tbl
FOR XML PATH('')
)
,1,1,'')
Then the query like this:
DECLARE #query NVARCHAR(4000)=
N'SELECT
*
FROM
(
SELECT
*
FROM
(
SELECT
PhoneBook.ID,
PhoneBook.Name,
field.Caption,
rel.Value
FROM
#PhoneBook AS PhoneBook
JOIN #PhoneBook_DynamicField_Rel AS rel
ON PhoneBook.ID = rel.PhoneBookID
JOIN #DynamicField AS field
ON rel.DynamicFieldID=field.ID
) AS SourceTable
) AS p
PIVOT
(
MAX(Value) FOR Caption IN('+#cols+')
) AS pvt'
EXECUTE(#query)
Then in my case I will drop the temp tables:
DROP TABLE #PhoneBook
DROP TABLE #DynamicField
DROP TABLE #PhoneBook_DynamicField_Rel
What you need is dynamic pivot:
declare #collist nvarchar(max)
SET #collist = stuff((select distinct ',' + QUOTENAME(caption)
FROM DynamicField
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
declare #q nvarchar(max)
set #q = '
select PhoneBookID, Name, ' + #collist + '
from (
select PhoneBookID, Name, Caption, Value
from (
select PhoneBookID, Name, Caption, Value
from PhoneBook pb
inner join PhoneBook_DynamicField_Rel pbdf on pb.ID = pbdf.PhoneBookID
inner join DynamicField df on df.ID = pbdf.DynamicFieldID
) as x
) as source
pivot (
max(Value)
for caption in (' + #collist + ')
) as pvt
'
exec (#q)

TSQL transform row values into one column table

Source Table
Col1 |Col2 |Col3 |Col4 | Col5
----------------------------------
hi | this | is | a | test
Destination Table
RowValues|
----------
hi
this
is
a
test
I am using Dynamic SQL.
Any help ?
This is my code , just change table name and the Id in the where clause to what suits you
DECLARE #sql nVARCHAR(max), #TableName nvarchar(100), #where nvarchar(max)
set #TableName = 'stockItems'
set #where= ' where id = 2'
select #sql ='Select '
select #sql = #sql+ + ' '''+ [name] +' = ''+ cast(' + [name] + ' as nvarchar(10)) as '+[name]+', '
from sys.columns where object_name (object_id) = #TableName
set #sql = stuff(#sql, len(#sql), 1, '') + ' From '+#TableName+ #where
print #sql
set #sql = REPLACE(#sql,', From',' From')
set #sql = #sql + ' '
print #sql
exec(#sql)
Now I need to create a new table that has one column that hold holds each value as a row
Thanks to #Mahmoud-Gamal
The solution should be something like below
declare #cols nvarchar(max)
select #cols = STUFF((SELECT distinct ',' +
QUOTENAME(column_name)
FROM information_schema.columns
WHERE table_name = 'vehicles'
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
, 1, 1, '');
declare #statement nvarchar(max)
set #statement ='
SELECT
ColumnName, Value
FROM
Vehicles
UNPIVOT
(
Value
FOR ColumnName
IN
(
'+#cols+'
)
)
AS A'
execute(#statement)
Please change the "vehicle" table name to any table on your database that has columns from different types (datetime, int and nvarchar) and the below error is shown
Any help ?
The type of column "Description" conflicts with the type of other columns specified in the UNPIVOT list.
Use the UNPIVOT table operator:
SELECT col AS RowValues
FROM table1 AS t
UNPIVOT
(
col
FOR value IN([col1],
[col2],
[col3],
[col4],
[col5])
) AS u;
SQL Fiddle Demo
This will give you:
| ROWVALUES |
|-----------|
| hi |
| this |
| is |
| a |
| test |
Update:
In case you don't know the names of the columns, and you want to do this dynamically, you have to do this using dynamic SQL.
But the problem is how to get the columns names?
You can get the columns names from the information_schema.columns, then concatenate them in one sql, then replace the columns' names in the UNPIVOT with this string, and execute that statement dynamically like this:
DECLARE #cols AS NVARCHAR(MAX);
DECLARE #query AS NVARCHAR(MAX);
select #cols = STUFF((SELECT distinct ',' +
QUOTENAME(column_name)
FROM information_schema.columns
WHERE table_name = 'Table1'
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
, 1, 1, '');
SELECT #query = ' SELECT col AS RowValues
FROM table1 AS t
UNPIVOT
(
val
FOR col IN ( ' + #cols + ' )
) AS u;';
EXECUTE(#query);
Updated SQL Fiddle Demo
I believe you want this
Select Col1 + Col2 + Col3 + Col4 + Col5 From Table
Or may be following
Select Col1 From Table1
union Select Col2 From Table1
union Select Col3 From Table1
union Select Col4 From Table1
union Select Col5 From Table1 ;

Resources