Create embedded column xml with a sql query - sql-server

I have a table with below records in it.
+------------+---------+
| State |Strength |
+------------+---------+
| AR | 10000 |
| AK | 20000 |
+------------+---------+
I want to general xml in the below format
<Fields><AR>10000</AR><AK>20000</AK></Fields>
What I've tried so far.
SELECT '<'+State+'>' + Strength+'</'+State+'>'
FROM tbl
FOR XML PATH (''), ROOT('Fields')
Result I get - <Fields><AR>10000</AR><AK>20000</AK></Fields>

You should use type for xml path and value method
DECLARE #SampleData AS TABLE (State varchar(20), Strength int)
INSERT INTO #SampleData
VALUES ('AR', 10000), ('AK', 20000) ,('MP', 30000)
SELECT (SELECT CONCAT('<',sd.State,'>', sd.Strength, '</',sd.State, '>')
FROM #SampleData sd
FOR XML PATH(''), TYPE).value('.[1]', 'nvarchar(max)')
Reference link: Type for xml sql
Or simple query like that
DECLARE #SampleData AS TABLE (State varchar(20), Strength int)
INSERT INTO #SampleData
VALUES ('AR', 10000), ('AK', 20000) ,('MP', 30000)
DECLARE #xml nvarchar(max) = N'<Fields>'
SELECT #xml += CONCAT('<',sd.State,'>', sd.Strength, '</',sd.State, '>')
FROM #SampleData sd
SET #xml += N'</ Fields>'
SELECT #xml

TriV's would be my first choice (already +1)
But, another option (just for fun) is via a PIVOT ... dynamic or not
Dynamic
Declare #SQL varchar(max) = Stuff((Select Distinct ',' + QuoteName([State]) From tbl Order by 1 For XML Path('')),1,1,'')
Select #SQL = '
Select *
From (
Select *
From (
Select Col=[State]
,Val=[Strength]
From tbl
) A
Pivot (max([Val]) For [Col] in ('+#SQL+') )p
) A
for XML Path(''''),Root(''Fields'')
'
Exec(#SQL)
Static
Select *
From (
Select *
From (
Select Col=[State]
,Val=[Strength]
From tbl
) A
Pivot (max([Val]) For [Col] in ([AK],[AR]) )p
) A
for XML Path(''),Root('Fields')
Both Return
<Fields>
<AK>20000</AK>
<AR>10000</AR>
</Fields>

Related

Convert Row data (Dates ) in Column headers in SQL

hello friends i m trying to convert row Data with dates in column headers
this is my sql attendanceData Table
Normal Table
Original Data
and i want to convert row dates into column headers like this
Transpose
can someone tell me how i can do this in sql
i m sure using pivot i can,
so i tried sql query to pivot
SELECT Enterprise_ID, Date, Attendance
FROM attendanceData natural
join ( SELECT Enterprise_ID
FROM attendanceData
group BY Enterprise_ID
)
pivot (max(P) for Attendance in ('P' as P, 'WO' as WO)
I tried using dynamic pivot
Sample script to generate data:
create table #a
(
entrprise_id varchar(50),
datee date,
attendance varchar(10)
)
insert into #a values
('james','2018-12-22','p'),
('james','2018-12-23','p'),
('pick','2018-12-23','p'),
('rick','2018-12-23','p'),
('pick','2018-12-22','p'),
('rick','2018-12-22','p')
PIVOT Query:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(c.datee)
FROM #a c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT entrprise_id, ' + #cols + ' from
(
select*
from #A
) x
pivot
(
max(attendance)
for datee in (' + #cols + ')
) p '
execute(#query)
or
select *
from
(
select *
from #A
) src
pivot
(
max(attendance)
for datee in ([2018-12-22], [2018-12-23])
) piv

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

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)

Multi Column to One Column

I am writing a trigger and I am using inserted
Inserted is a single row
like
ColumnX |ColumnY|ColumnZ|
=========================
A | B |C |
I want to insert results to another table like this
ColumnName |Value|
==================
ColumnX | A |
ColumnY | B |
ColumnZ | C |
I have a lot of tables how can I make this?
UNPIVOT the result set, then insert them:
INSERT INTO Anothertable(Columnname, value)
SELECT Columnname, value
FROM tablename t
UNPIVOT
(
value
FOR ColumnName IN(ColumnX, ColumnY, ColumnZ)
) AS u;
SQL Fiddle Demo
To do this dymaincally:
DECLARE #cols AS NVARCHAR(MAX);
DECLARE #query AS NVARCHAR(MAX);
select #cols = STUFF((SELECT distinct ',' +
QUOTENAME(Columnname)
FROM table1 t
UNPIVOT
(
value
FOR ColumnName IN(ColumnX, ColumnY, ColumnZ)
) AS u
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
, 1, 1, '');
SET #query = 'SELECT Columnname, value
FROM table1 t
UNPIVOT
(
value
FOR ColumnName IN( ' + #cols + ' )
) AS u;'
execute(#query);
Updated SQL Fiddle Demo
CREATE TRIGGER TriggerName
ON YourDatabase.TableName
AFTER INSERT
AS
BEGIN
INSERT INTO OtherTable (ColumnX, ColumnY, ColumnZ)
SELECT ColumnX, ColumnY, ColumnZ
FROM inserted
END
GO

SQL - How to insert multiple records as one record without pivot?

i want to create a query from multiple records as one record , but i don't want to use Pivot, is there any solutions?
here's the table :
ID Element_Name Value
1 Parmitha 100
2 Anggun 200
3 Chandra 300
4 BagusofTerror 400
and i want the result is like this :
paramitha , anggun, chandra , bagusofterror
100 , 200, 300, 400
You can use for xml path ('') to transpose the values of a column.
For example, you could write
select Element_Name + ', '
from TheTable
for xml path ('');
To get Parmitha, Anggun, Chandra, BagusofTerror,
Here's a live demo: http://www.sqlfiddle.com/#!3/71f88/24
You can also use COALESCE to pivot a results set of columns into a varchar variable:
CREATE TABLE #Pivot
(ID int, Element_Name varchar(50), Value int)
INSERT #Pivot values (1,'Parmitha',100)
INSERT #Pivot values (2,'Anggun',200)
INSERT #Pivot values (3,'Chandra',300)
INSERT #Pivot values (4,'BagusofTerror',400)
DECLARE #titles VARCHAR(1000)
DECLARE #values VARCHAR(1000)
SET #titles = ''
SET #values = ''
SELECT #titles = #titles + COALESCE(Element_Name + ',' , '')
FROM #Pivot ORDER BY ID
SELECT #values = #values + COALESCE(convert(varchar, Value) + ',' , '')
FROM #Pivot ORDER BY ID
SELECT #titles
UNION ALL
SELECT #values
Gives:
Parmitha,Anggun,Chandra,BagusofTerror,
100,200,300,400,
Try this :-
Select
MAX(CASE WHEN colID = 1 THEN value ELSE NULL END) AS [Parmitha],
MAX(CASE WHEN colID = 2 THEN value ELSE NULL END) AS [Anggun],
MAX(CASE WHEN colID = 3 THEN value ELSE NULL END) AS [Chandra],
MAX(CASE WHEN colID = 4 THEN value ELSE NULL END) AS [BagusofTerror]
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY ID) AS colID,
ID,
Element_Name,
value
FROM Sample
) AS d
SQL DEMO
Taking Wolf's answer into consideration ,using dynamic query and xml path
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ','
+ convert(varchar(max), Element_Name, 120)
from Sample
FOR XML PATH(''), TYPE
).value('.', 'varchar(MAX)')
,1,1,'')
set #query = 'SELECT' + #cols + ' from
(
select value, Element_Name
from Sample
) x
pivot
(
max(value)
for Element_Name in (' + #cols + ')
) p '
execute(#query);
Demo
By the way y don't u use PIVOT .Using PIVOT the same result can be achieved
Select [Parmitha],[Anggun],[Chandra],[BagusofTerror]
FROM
(
Select value,element_name from Sample
)src
pivot
(
max(value)
for Element_Name in ([Parmitha],[Anggun],[Chandra],[BagusofTerror])
)pvt

Resources