Data insert into table dynamically - sql

Example query which I used
Declare #DataColumn table (id int not null primary key identity(1,1), ColumnName Nvarchar(250),DataValue Nvarchar(250))
insert into #DataColumn
select DataColumnName, DataValue
from CustomObjectMappingTable obm
join #price_tmp temp on obm.ObjectFieldName = temp.FieldName
where temp.DataValue <> ''
select * from #DataColumn
Result is :
id ColumnName DataValue
-------------------------
1 Column_1 Umar Mehmood
2 Column_2 27
3 Column_3 21-nov-1992
4 Column_4 Male
5 Column_5 Gujar Khan District RWP
I have data into temp table and I need to insert into physical table using temp table. I want to use from temptable first columndata as " ColumnName" and second column data as "Data" how can I do this any one help me please?
Query for inserting
insert into CustomData (#DataColumn.ColumnName)
select *
from
(select DataValue, ColumnName
from #DataColumn) d
pivot
(max(DataValue)
for ColumnName in (ColumnName)
) piv;
Need it dynamically

Try the following:
DECLARE #DataColumn table ( id int, ColumnName varchar(50), DataValue varchar(50) );
INSERT INTO #DataColumn VALUES
( 1, 'Column_1', 'Umar Mehmood' ),
( 2, 'Column_2', '27' ),
( 3, 'Column_3', '21-nov-1992' ),
( 4, 'Column_4', 'Male' ),
( 5, 'Column_5', 'Gujar Khan District RWP' );
DECLARE #insert_columns varchar(MAX) = (
SELECT STUFF(
( SELECT ',[' + ColumnName + ']' FROM #DataColumn ORDER BY id FOR XML PATH( '' ) ),
1,
1,
''
)
);
DECLARE #insert_values varchar(MAX) = STUFF ( (
SELECT ',(' + STUFF(
( SELECT ',''' + DataValue + '''' FROM #DataColumn ORDER BY id FOR XML PATH( '' ) ),
1,
1,
''
) + ')'
), 1, 1, '' );
DECLARE #tsql varchar(MAX) = 'INSERT INTO CustomData (' + #insert_columns + ') VALUES ' + #insert_values + ';';
--EXEC(#tsql); -- Uncomment this line to execute the dynamic SQL.
PRINT #tsql;
The printed dynamic SQL:
INSERT INTO CustomData ([Column_1],[Column_2],[Column_3],[Column_4],[Column_5]) VALUES ('Umar Mehmood','27','21-nov-1992','Male','Gujar Khan District RWP');

We can do it using pivot table for dynamically
DECLARE #cols NVARCHAR(MAX), #query NVARCHAR(MAX) , #DataValues NVARCHAR(max);
SET #cols = STUFF( (SELECT DISTINCT ','+QUOTENAME(ColumnName) FROM ##DataColumn c FOR XML PATH(''), TYPE ).value('.', 'nvarchar(max)'), 1, 1, '');
SET #query = 'SELECT * from ( select [ColumnName],[DataValue] from ##DataColumn
) as sourcetable pivot (max(DataValue) for[ColumnName] in ('+#cols+')) p order by 1 ';
Insert into customdata ( [Column_1],[Column_2],[Column_3],[Column_4],[Column_5])
SELECT * from ( select [ColumnName],[DataValue] from #DataColumn ) as sourcetable
pivot (max(DataValue) for[ColumnName] in ([Column_1],[Column_2],[Column_3],[Column_4],[Column_5])) p order by 1

Related

Pivot multiple columns with a column value repeats for each new column

I need your help to build an sql query/sp for the following output.
My table is with the following data:
I would like to generate output like the following:
Kindly note, here, FieldName are not just four as in the table, it varies.
Find below the data:
CREATE TABLE #Results
(
FieldName nvarchar(50),
FieldValue nvarchar(50),
RecordStaus int
);
INSERT INTO #Results(FieldName,FieldValue,RecordStaus)
VALUES ('Coverage',NULL,1)
,('Premium',NULL,2)
,('F1',100,1)
,('F2',100,1)
,('Coverage',200,1)
,('Premium',10,1)
,('F1',50,1)
,('F2',NULL,3)
,('Coverage',300,1)
,('Premium',45,1)
,('F1',24,1)
,('F2',NULL,1)
,('Coverage',450,3)
,('Premium',12,3)
,('F1',50,1)
,('F2',NULL,1);
You can try this:
CREATE TABLE #Results
(
id int identity(1,1),
FieldName nvarchar(50),
FieldValue nvarchar(50),
RecordStaus int
);
INSERT INTO #Results(FieldName,FieldValue,RecordStaus)
VALUES ('Coverage',NULL,1)
,('Premium',NULL,2)
,('F1',100,1)
,('F2',100,1)
,('Coverage',200,1)
,('Premium',10,1)
,('F1',50,1)
,('F2',NULL,3)
,('Coverage',300,1)
,('Premium',45,1)
,('F1',24,1)
,('F2',NULL,1)
,('Coverage',450,3)
,('Premium',12,3)
,('F1',50,1)
,('F2',NULL,1);
DECLARE #DynamicTSQLStatement NVARCHAR(MAX)
,#Columns NVARCHAR(MAX);
SELECT #Columns = STUFF
(
(
SELECT *
FROM
(
SELECT DISTINCT ',[' + CAST([FieldName] AS NVARCHAR(50)) + ']'
FROM #Results
UNION
SELECT DISTINCT ',[' + CAST([FieldName] + '_RecordStaus' AS NVARCHAR(50)) + ']'
FROM #Results
) DS ([FieldName])
FOR XML PATH(''), TYPE
).value('.', 'VARCHAR(MAX)')
,1
,1
,''
);
SET #DynamicTSQLStatement = N'
SELECT *
FROM
(
SELECT [FieldName]
+ CASE WHEN [Column] = ''RecordStaus'' THEN ''_RecordStaus'' ELSE '''' END AS [FieldName]
,[rowID]
,[Value]
FROM
(
SELECT [FieldName]
,[FieldValue]
,CAST([RecordStaus] AS NVARCHAR(50))
,ROW_NUMBER() OVER (PARTITION BY [FieldName] ORDER BY [id])
FROM #Results
) DS ([FieldName], [FieldValue], [RecordStaus], [rowID])
UNPIVOT
(
[Value] FOR [Column] IN ([FieldValue], [RecordStaus])
) UNPVT
) ReadyForPivot
PIVOT
(
MAX([Value]) FOR [FieldName] IN (' + #Columns +')
) PVT;
';
EXEC sp_executesql #DynamicTSQLStatement;
DROP TABLE #Results;
Few notes:
I have added id column in order to know the value for which row / in your real case you can use ordering by something else or SELECT 1 in the ROW_NUMBER function; you need such way in order to be sure the results are deterministic;
I am using dynamic SQL in order to make the query work for various values of FildName column - if you need specific order of the columns, you can do this using ORDER BY clause in the FOR XML clause. For example:
SELECT #Columns = STUFF
(
(
SELECT *
FROM
(
SELECT DISTINCT ',[' + CAST([FieldName] AS NVARCHAR(50)) + ']'
FROM #Results
UNION
SELECT DISTINCT ',[' + CAST([FieldName] + '_RecordStaus' AS NVARCHAR(50)) + ']'
FROM #Results
) DS ([FieldName])
ORDER BY [FieldName] DESC -- you can order the columns as you like
FOR XML PATH(''), TYPE
).value('.', 'VARCHAR(MAX)')
,1
,1
,''
);
Then add the #columns variable value in the dynamic SQL:
SET #DynamicTSQLStatement = N'
SELECT' + #columns + ' ...

How to merge 2 rows of a table into 1 according to a third column by making it as a header

net mvc so as a part of my learning I came accross this situation
I have output of a query in a temp table as
Reporting To Manager UserType
----------------------------------------------------------------------------------
VEDAYyyar H ( MI124557 ) P KUMAR ( N156787 ) ASM
VEDAYyyar H ( MI124557 ) H MIKAHAVA ( N24578 ) RSM
VEDAYyyar H ( MI124557 ) VNKAR IJ ( N245788) NSM
I want to format it as
ReportingTo RSM ASM NSM
--------------------------------------------------------------------
so the three rows can be made into a single row
Any help will be appreciated
Use PIVOT table :
CREATE TABLE [dbo].[Table1]
(
[ReportingTo] [nvarchar](50) NULL,
[Manager] [nvarchar](50) NULL,
[UserType] [nvarchar](30) NULL
)
INSERT INTO Table1 (ReportingTo,Manager,UserType)
SELECT 'VEDAMURTHY H C ( HI00007989 )','P M ASHOK KUMAR ( HI00004297
)','ASM' UNION ALL
SELECT 'VEDAMURTHY H C ( HI00007989 )','H S KESHAVA KUMAR ( HI00004056
)','RSM' UNION ALL
SELECT 'VEDAMURTHY H C ( HI00007989 )','VIJAY SHANKAR IYER J (
HI00006779)','NSM'
SELECT *
FROM
(
SELECT *
FROM Table1
) A
PIVOT
(
MAX(Manager) FOR UserType IN ([ASM],[RSM],[NSM])
)pvt
you can use pivot
select * from yourtable
pivot (max(Manager) for UserType in ([ASM],[RSM],[NSM])) p
If you have more columns and looking for dynamic columns in UserType then you can use dynamic query as below
declare #cols varchar(max)
declare #query nvarchar(max)
select #cols = stuff((select ','+QuoteName(UserType) from #yourtable group by UserType for xml path('')),1,1,'')
SET #query = 'select [Reporting To], ' + #cols + ' from ( ' + ' select [Reporting To], [Manager], [UserType] from Yourtable ) a '
SET #Query = #query + ' pivot (max(Manager) for UserType in (' + #cols + ')) p '
exec sp_executesql #query
Output as below:
+-------------------------------+--------------------------------+------------------------------------+----------------------------------+
| Reporting To | ASM | NSM | RSM |
+-------------------------------+--------------------------------+------------------------------------+----------------------------------+
| VEDAMURTHY H C ( HI00007989 ) | P M ASHOK KUMAR ( HI00004297 ) | VIJAY SHANKAR IYER J ( HI00006779) | H S KESHAVA KUMAR ( HI00004056 ) |
+-------------------------------+--------------------------------+------------------------------------+----------------------------------+
IF OBJECT_ID('Tempdb..#temp') IS NOT NULL
DROP TABLE #TEMP
DECLARE #Temp TABLE (
ReportingTo NVARCHAR(max)
,Manager NVARCHAR(max)
,UserType VARCHAR(20)
)
INSERT INTO #Temp
SELECT 'VEDAYyyar H ( MI124557 )', 'P KUMAR ( N156787 )' , 'ASM' Union all
SELECT 'VEDAYyyar H ( MI124557 )', 'H MIKAHAVA ( N24578 )' , 'RSM' Union all
SELECT 'VEDAYyyar H ( MI124557 )', ' VNKAR IJ ( N245788)' , 'NSM'
SELECT *
INTO #TEMP
FROM #Temp
DECLARE #Sql NVARCHAR(max)
,#dynamicCol NVARCHAR(max)
SELECT #dynamicCol = STUFF((
SELECT DISTINCT ', ' + QUOTENAME(UserType)
FROM #TEMP
FOR XML PATH('')
), 1, 1, '')
--Getting the column names Dynamically
SELECT #dynamicCol
SET #Sql = '
SELECT ReportingTo,' + #dynamicCol + ' From
(
SELECT ReportingTo,Manager,UserType From
#TEMP
)AS Src
PIVOT
(
MAX(Manager) For UserType IN (' + #dynamicCol + ')
)
AS Pvt'
PRINT #Sql
EXEC (#Sql)
OutPut
ReportingTo ASM NSM RSM
-------------------------------------------------------------------------------------------------
VEDAYyyar H ( MI124557 ) P KUMAR ( N156787 ) VNKAR IJ ( N245788) H MIKAHAVA ( N24578 )

How to provide custom name to column in pivoting

I have a table like this:
id unit
1 mm
2 cm
3 kg
When I perform pivot operation on this, I am getting result as follows:
1 2 3
mm cm kg
Is it possible to get custom column names here, something like this:
d1 d2 d3
mm cm kg
I am using Pivot for this as:
IF OBJECT_ID('tempdb..#t') IS NOT NULL
DROP TABLE #t
GO
CREATE table #t
(id varchar(max),unit varchar(max))
insert into #t (id,unit)values
(1,'kg'),
(2,'cm'),
(3,'mm'),
(4,'m')
DECLARE #statement NVARCHAR(max)
,#columns NVARCHAR(max)
SELECT #columns = ISNULL(#columns + ',', '') + N'[' + cast(tbl.id as varchar(max)) + ']'
FROM (
SELECT DISTINCT id
FROM #t
) AS tbl
SELECT #statement = 'select *
INTO ##temp
from (
SELECT id,[unit]
FROM #t
) as s
PIVOT
(max(unit) FOR id in(' + #columns + ')) as pvt
'
EXEC sp_executesql #statement = #statement
SELECT * FROM ##temp
DROP TABLE #t
DROP TABLE ##temp
Is it possible?
Thanks
IF OBJECT_ID('tempdb..#t') IS NOT NULL
DROP TABLE #t
GO
CREATE TABLE #t (
id VARCHAR(10),
unit VARCHAR(100)
)
INSERT INTO #t (id, unit)
VALUES
('1', 'kg'),
('2', 'cm'),
('3', 'mm'),
('4', 'mm')
DECLARE #SQL NVARCHAR(MAX), #columns NVARCHAR(MAX)
SELECT #columns = STUFF((
SELECT ',[D' + id + ']'
FROM #t
FOR XML PATH('')), 1, 1, '')
SELECT #SQL = '
SELECT *
FROM (
SELECT [unit], col = N''D'' + id
FROM #t
) s
PIVOT (MAX(unit) FOR col IN (' + #columns + ')) p'
EXEC sys.sp_executesql #SQL
Just add a prefix to your ID. Example
SELECT #statement = 'select * INTO ##temp from
( SELECT [id] = ''d''+id,[unit] FROM #t ) as s
PIVOT
(max(unit) FOR id in(' + #columns + ')) as pvt '
Also it's terrible practice to use global temp tables! Especially one named ##temp
You can use a CASE expression with a dynamic sql query.
CREATE TABLE #t
(
id INT,
unit VARCHAR(2)
);
INSERT INTO #t VALUES
(1,'mm'),
(2,'cm'),
(3,'kg');
DECLARE #query AS VARCHAR(MAX);
SELECT #query = 'SELECT ' +
STUFF
(
(
SELECT DISTINCT ',MAX(CASE WHEN id = '+ CAST(id AS VARCHAR(10))
+ ' THEN unit END) AS d' + CAST(id AS VARCHAR(10))
FROM #t
FOR XML PATH('')
),
1,1,'');
SELECT #query += ' FROM #t;';
EXECUTE(#query);
Result
+----+----+----+
| d1 | d2 | d3 |
+----+----+----+
| mm | cm | kg |
+----+----+----+
SELECT #statement = 'select * INTO ##temp from ( SELECT ''d''+id AS [id],[unit] FROM #t ) as s PIVOT (max(unit) FOR id in(' + #columns + ')) as pvt '

SQL Server 2008 R2 table Pivot

I have a table with 3 columns.
The column color can be dynamic, now I have 4 elements, after I can get 6 elements or more.
How to write query to do this ?
Thank you
You can use dynamic sql like:
CREATE TABLE #t
(
Company CHAR(3) ,
Value INT ,
color NVARCHAR(10)
)
GO
DECLARE #c NVARCHAR(MAX) = '['
DECLARE #s NVARCHAR(MAX) = ''
INSERT INTO #t
VALUES ( 'AAA', 2, 'red' ),
( 'AAA', 2, 'white' ),
( 'BBB', 2, 'white' ),
( 'BBB', 3, 'blue' ),
( 'CCC', 3, 'pink' ),
( 'FFF', 4, 'blue' )
SELECT #c = #c + color + '],['
FROM ( SELECT DISTINCT
color
FROM #t
) AS t
SELECT #c = SUBSTRING(#c, 1, LEN(#c) - 2)
SET #s = ';WITH cte AS
(
SELECT Company, Value, color FROM #t
)
SELECT Company, ' + #c + ' FROM cte
PIVOT(MAX(Value) FOR color IN(' + #c + ')) AS p'
EXEC(#s)
Output:
Company blue pink red white
AAA NULL NULL 2 2
BBB 3 NULL NULL 2
CCC NULL 3 NULL NULL
FFF 4 NULL NULL NULL
Apply appropriate aggregation in pivot clause.
Using PIVOT. Learn SQL SERVER – PIVOT and UNPIVOT Table Examples
SELECT Company, red, white, blu, pink
FROM TableName
PIVOT(MAX(Value) FOR Color IN(ed, white, blu, pink))AS Piv
Dynamic Pivot:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(c.Color)
FROM TableName c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT Company, ' + #cols + ' from
(
select Company
, value
, color
from TableName
) x
pivot
(
max(value)
for color in (' + #cols + ')
) p '
execute(#query)

Flattening a Single Table

I am looking for a very basic flattening. I have a table in the database which provides each field for the employee in a different row.
EX
EMPLOYEE GROUP_NAME
81 BNEEO55
81 BNELLIG
81 LPKAPE
81 HRFT
90 BNRETINV
....
I would like to create a view which reports the data as:
EMPLOYEE Group1 Group2 Group3 Group4 Group5
81 BNEEO55 BNELLIG LPKAPE HRFT NULL
90 NULL NULL NULL NULL BNRETINV
OR
EMPLOYEE BNEEO55 BNELLIG LPKAPE HRFT BNRETINV
81 YES YES YES YES NO
90 NO NO NO NO YES
You need to PIVOT the data, if you are using SQL-Server 2008 or later you can use the PIVOT function:
CREATE TABLE #T (Employee INT, Group_name VARCHAR(50))
INSERT #T VALUES (81, 'BNEEO55'), (81, 'BNELLIG'), (81, 'LPKAPE'), (81, 'HRFT'), (90, 'BNRETINV')
SELECT Employee,
COALESCE([BNEEO55],'No') AS [BNEEO55],
COALESCE([BNELLIG],'No') AS [BNELLIG],
COALESCE([BNRETINV],'No') AS [BNRETINV],
COALESCE([HRFT],'No') AS [HRFT],
COALESCE([LPKAPE],'No') AS [LPKAPE]
FROM ( SELECT *, 'Yes' [Data]
FROM #T
) d
PIVOT
( MAX(Data)
FOR Group_Name IN ([BNEEO55], [BNELLIG], [BNRETINV], [HRFT], [LPKAPE])
) pvt
But it sounds like you need to do it dynamically if your data is changing. Something like the following would work:
DECLARE #SQL NVARCHAR(MAX) = '',
#Cols NVARCHAR(MAX) = ''
SELECT #SQL = #SQL + ',' + QUOTENAME(Group_Name),
#Cols = #Cols + ',COALESCE(' + QUOTENAME(Group_Name) + ',''No'') AS ' + QUOTENAME(Group_Name)
FROM ( SELECT DISTINCT Group_Name
FROM #T
) T
SET #SQL = '
SELECT Employee, ' + STUFF(#Cols, 1, 1, '') +
'FROM ( SELECT *, ''Yes'' [Data]
FROM #T
) d
PIVOT
( MAX(Data)
FOR Group_Name IN (' + STUFF(#SQL, 1, 1, '') + ')
) pvt'
EXECUTE SP_EXECUTESQL #SQL
This builds up the same query as the first one, but means that when a new group name is added the query doesn't have to be altered.
EDIT
To create and call this as a stored procedure:
CREATE TABLE T (Employee INT, Group_name VARCHAR(50))
INSERT T VALUES (81, 'BNEEO55'), (81, 'BNELLIG'), (81, 'LPKAPE'), (81, 'HRFT'), (90, 'BNRETINV')
GO
CREATE PROCEDURE PivotT
AS
DECLARE #SQL NVARCHAR(MAX) = '',
#Cols NVARCHAR(MAX) = ''
SELECT #SQL = #SQL + ',' + QUOTENAME(Group_Name),
#Cols = #Cols + ',COALESCE(' + QUOTENAME(Group_Name) + ',''No'') AS ' + QUOTENAME(Group_Name)
FROM ( SELECT DISTINCT Group_Name
FROM T
) T
SET #SQL = '
SELECT Employee, ' + STUFF(#Cols, 1, 1, '') +
'FROM ( SELECT *, ''Yes'' [Data]
FROM T
) d
PIVOT
( MAX(Data)
FOR Group_Name IN (' + STUFF(#SQL, 1, 1, '') + ')
) pvt'
EXECUTE SP_EXECUTESQL #SQL
GO
EXECUTE PivotT