I have a dynamic pivoted query which generates a result set and I want to insert that data into a table. But the problem is columns are dropped or generated by the time. So by the time I cannot predict columns. That is why I created a dynamic pivoted dataset. So how to insert that data set into table?
One solution is to drop and recreate the table every time but I don't know how to do it. I tried CTE, TEMP table but EXEC support only select, insert, update, delete statement:
DECLARE #columns NVARCHAR(MAX), #sqlquery NVARCHAR(MAX), #orderby Nvarchar(MAX),#value Nvarchar(max);
SET #columns = N'';
SET #value=N'0'
SELECT #columns += N', ' + QUOTENAME([Note_Type])
FROM
(
SELECT distinct
No_T
FROM [DS_DM].[dbo].[DAILY_TABLE]
where No_T not in (570,80,150,590,80,99)
)as A order by No_T
SET #sqlquery = N'
Select
K._Number
,D.C_Number
,' + STUFF(#columns, 1, 2, '') + '
from
(
select
_Number
,' + STUFF(#columns, 1, 2, '') + '
from
(
select distinct
right(REPLICATE('+#value+',11) +_Number,11) as [_Number]
,No_t
,No_T_Des
FROM [DS_DM].[dbo].[DAILY_TABLE]
where No_T not in (570,80,150,590,80,99)
)AS J
pivot
(
count(No_T_Des) FOR [No_t] IN ('
+ STUFF(REPLACE(#columns, ', p.[', ',['), 1, 1, '')
+ ')
)P
)K
left join
[DS_DM].[dbo].[D_TABLE] D on k._Number = D._Number
';
EXEC sp_executesql #sqlquery
I've modified your code to reflect my proposed solution.
IF OBJECT_ID (N'NEW_TABLE', N'U') IS NOT NULL
BEGIN
DROP TABLE NEW_TABLE
END
DECLARE #columns NVARCHAR(MAX), #sqlquery NVARCHAR(MAX), #orderby Nvarchar(MAX),#value Nvarchar(max);
SET #columns = N'';
SET #value=N'0'
SELECT #columns += N', ' + QUOTENAME([Note_Type])
FROM
(
SELECT distinct
No_T
FROM [DS_DM].[dbo].[DAILY_TABLE]
where No_T not in (570,80,150,590,80,99)
)as A order by No_T
SET #sqlquery = N'
Select
K._Number
,D.C_Number
,' + STUFF(#columns, 1, 2, '') + '
INTO NEW_TABLE
from
(
select
_Number
,' + STUFF(#columns, 1, 2, '') + '
from
(
select distinct
right(REPLICATE('+#value+',11) +_Number,11) as [_Number]
,No_t
,No_T_Des
FROM [DS_DM].[dbo].[DAILY_TABLE]
where No_T not in (570,80,150,590,80,99)
)AS J
pivot
(
count(No_T_Des) FOR [No_t] IN ('
+ STUFF(REPLACE(#columns, ', p.[', ',['), 1, 1, '')
+ ')
)P
)K
left join
[DS_DM].[dbo].[D_TABLE] D on k._Number = D._Number
';
EXEC sp_executesql #sqlquery
So I found the answers to my questions.
there are 2 fileds which remais static every time. so I've created ETL that drop that table and recreate every single day with those two fileds. and rest of the 66 columns which are dynamic (drops or newly created) every day. so i've made a cursor for that which loop through all of that categories and altering that table that've created and added that code to ETL
So bassically Every single day that ETL Runs Drop the existing table, Create new table with the 2 static filds and altering same table using cursor with the dynamic filds.
Related
I have a query that provides some data I want to save this data in a temp table or view. Please help
The query is given below:
IF OBJECT_ID('tempdb..#NLSPMTS3_tmp') IS NOT NULL
DROP TABLE #NLSPMTS3_tmp
SELECT *
INTO #NLSPMTS3_tmp
FROM vwNLSPayments4
DECLARE #Columns AS VARCHAR(MAX)
SELECT #Columns = COALESCE(#Columns + ', ','') + QUOTENAME(b.mop_fpd)
FROM (SELECT DISTINCT mop_fpd FROM #NLSPMTS3_tmp) AS B
ORDER BY B.mop_fpd
-- You can't remove nulls from a PIVOT, so you have to create a second set of column names
DECLARE #NullColumns as VARCHAR(MAX)
SELECT #NullColumns =
COALESCE(#NullColumns + ', ','') + 'ISNULL(' + QUOTENAME(b.mop_fpd) + ', 0) ' + QUOTENAME(b.mop_fpd)
FROM (Select DISTINCT mop_fpd FROM #NLSPMTS3_tmp) AS B
ORDER BY B.mop_fpd
DECLARE #SQL as NVARCHAR(MAX)
SET #SQL = 'SELECT acctrefno, ' + #NullColumns + '
FROM
(SELECT payment_amount, acctrefno, mop_fpd
FROM
nlsdev.dbo.vwnlsPayments2
) as PivotData
PIVOT
(sum(payment_amount) FOR mop_fpd IN (' + #Columns + ')) AS PivotResult ORDER BY acctrefno'
EXEC (#SQL)
I just simply put create a view as <above SQL query> but it did not work.
Hello everyone and thanks in advance.
I have two tables that I need to merge using Pivot.
1)Table with list of users:
#Tbl_staff(UserId INT,
Name NVARCHAR(MAX),
Surname NVARCHAR(MAX),
Level NVARCHAR (MAX)
)
2) Table with users' actions:
#Tbl_acts(Day DATE,
UserIdfk INT,
WorkedHours NVARCHAR(MAX),
Absence NVARCHAR(MAX),
Festivity NVARCHAR(2)
)
Table 2 has a complete month for each ID and for each day the action recorded. (Hours worked, hours of absence and type of absence, if the day is a holiday)..
It can also be null if in the db there is no action for that person on that day.
I wrote my Pivot like this:
DECLARE #columns NVARCHAR(MAX), #sql NVARCHAR(MAX);
SET #columns = N'';
SELECT #columns += N', p.' + QUOTENAME((cast(USERID AS VARCHAR(MAX)) + ' ' + NAME+ ' ' + SURNAME+' ' +(ISNULL (LEVEL,''))))
FROM (SELECT p.USERID,p.NAME,p.SURNAME,p.LEVEL FROM #TBL_STAFF AS p
INNER JOIN #TBL_ACTS AS o
ON p.USERID = o.USERIDFK
GROUP BY p.USERID,P.NAME,P.SURNAME,P.LEVEL) AS x;
SET #sql = N'
SELECT DAY,' + STUFF(#columns, 1, 2, '') + '
FROM
(
SELECT DISTINCT o.DAY,IDU = CAST(p.USERID AS NVARCHAR(MAX)), o.WORKEDHOURS
FROM #TBL_STAFF AS p, #TBL_ACTS AS o
where p.USERID= o.USERIDFK
) AS j
PIVOT
(
MAX(WORKEDHOURS) FOR IDU IN ('
+ STUFF(REPLACE(#columns, ', p.[', ',['), 1, 1, '')
+ ')
) AS p ORDER BY DAY;';
PRINT #sql;
EXEC sp_executesql #sql;
(Trying to show only the worked hours ... would be a good start)
It's the result: Column 'day' is ok(31 rows) and 'staff' too but it shows nothing inside it.
I'm trying to Pivot a Table on X and Y position. The table is in a format similar to below.
Each row has a value which is relative to its Row and Column Position.'AThing' and 'FileName' are to be ignored in the data set.
So if this was pivoted we would get:
Iv'e been trying for a while but can't seem to figure it out, any ideas?
EDIT: Number of Fields are dynamic per 'FileName'. I have managed to extract the column names but not the data using:
-- Construct List of Columns to Pivot
SELECT #PivotCols =
STUFF(
(SELECT ',' + QUOTENAME(FieldName)
FROM #Data
GROUP BY ColPos, FieldName
ORDER BY ColPos ASC
FOR XML PATH(''),TYPE).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET #PivotQuery =
SELECT ' + #PivotCols + N'
FROM
(
SELECT ColPos, FieldName
FROM #Data
GROUP BY ColPos, FieldName
) x
PIVOT
(
MIN(ColPos)
FOR FieldName IN (' + #PivotCols + N')
) p'
EXEC sp_executesql #PivotQuery
Please try this code:
DECLARE #columns NVARCHAR(MAX), #sql NVARCHAR(MAX);
SET #columns = N'';
SELECT #columns += N', p.' + QUOTENAME(FieldName)
FROM (SELECT distinct p.FieldName FROM Tablename AS p
) AS x;
SET #sql = N'
SELECT ' + STUFF(#columns, 1, 2, '') + '
FROM
(
SELECT p.Value, p.FieldName, p.RowPos
FROM Tablename AS p
) AS j
PIVOT
(
MAX(Value) FOR FieldName IN ('
+ STUFF(REPLACE(#columns, ', p.[', ',['), 1, 1, '')
+ ')
) AS p;';
PRINT #sql;
EXEC sp_executesql #sql;
I just wrote a script here but I have no idea how to save it as a view or a table. It is dynamically creating columns from rows
DECLARE #columns NVARCHAR(MAX), #sql NVARCHAR(MAX);
SET #columns = N'';
SELECT #columns += N', p.' + QUOTENAME([Period])
FROM (SELECT p.Period FROM dbo.[refv_IRR3_Op_Rev] AS p
INNER JOIN [dbo].[refv_IRR3_Op_Rev] AS o
ON p.RMDF = o.RMDF
GROUP BY P.Period) AS x;
SET #sql = N'
SELECT [Region]
,[LAU]
,[RMDF]
, ' + STUFF(#columns, 1, 2, '') + '
FROM
(
SELECT [Region]
,[LAU]
,[RMDF]
,[Period]
,[Net_Operating_Cashflow]
FROM [FTTx_Build].[dbo].[refv_IRR3_Op_Rev]
) AS j
PIVOT
(
SUM([Net_Operating_Cashflow]) FOR Period IN ('
+ STUFF(REPLACE(#columns, ', p.[', ',['), 1, 1, '')
+ ')
) AS p;';
PRINT #sql;
EXEC sp_executesql #sql;
How do I save it as a view or table?
short answer: you can't. However you can build a stored procedure from your code and call that when you need those results.
I am using SQL Server 2012. I will like to get final result from #sql into a temp table.Here is my code so far. Thanks for your help.
IF OBJECT_ID ('tempdb.dbo.#MY_DT_CTE') IS NOT NULL DROP TABLE #MY_DT_CTE
CREATE TABLE #MY_DT_CTE
([ROWID] INT NOT NULL IDENTITY (1,1)
,[YYYYMM] INT
)
; WITH MY_DT_CTE AS
(
SELECT CONVERT(INT,CONVERT(VARCHAR(6),EOMONTH(GETDATE(),-1),112)) AS [YYYYMM]
UNION
SELECT CONVERT(INT,CONVERT(VARCHAR(6),EOMONTH(GETDATE(),-2),112)) AS [YYYYMM]
UNION
SELECT CONVERT(INT,CONVERT(VARCHAR(6),EOMONTH(GETDATE(),-3),112)) AS [YYYYMM]
UNION
SELECT CONVERT(INT,CONVERT(VARCHAR(6),EOMONTH(GETDATE(),-4),112)) AS [YYYYMM]
UNION
SELECT CONVERT(INT,CONVERT(VARCHAR(6),EOMONTH(GETDATE(),-5),112)) AS [YYYYMM]
UNION
SELECT CONVERT(INT,CONVERT(VARCHAR(6),EOMONTH(GETDATE(),-6),112)) AS [YYYYMM]
)
INSERT INTO #MY_DT_CTE
SELECT [YYYYMM] FROM MY_DT_CTE
ORDER BY [YYYYMM] DESC;
-- SELECT * FROM #MY_DT_CTE
DECLARE #columns NVARCHAR(MAX), #sql NVARCHAR(MAX);
SET #columns = N'';
SELECT #columns += N', p.' + QUOTENAME(YYYYMM)
FROM (SELECT p.YYYYMM FROM #MY_DT_CTE AS p
GROUP BY p.YYYYMM) AS x;
SET #sql = N'
SELECT ' + STUFF(#columns, 1, 2, '') + '
FROM
(
SELECT p.YYYYMM FROM #MY_DT_CTE AS p
) AS j
PIVOT
(
COUNT(YYYYMM) FOR YYYYMM IN ('
+ STUFF(REPLACE(#columns, ', p.[', ',['), 1, 1,
'')
+ ')
) AS p;';
PRINT #sql;
EXEC sp_executesql #sql;
Need to bring this result #sql into a temp table.
201605 201606 201607 201608 201609 201610
An easy way would be to use a global temporary table. This can be selected into in the dynamic SQL scope to automatically have the desired schema and still be available after that exits.
SET #sql = N'
SELECT ' + STUFF(#columns, 1, 2, '') + '
INTO ##GlobalTemp
FROM
(
SELECT p.YYYYMM FROM #MY_DT_CTE AS p
) AS j
PIVOT
(
COUNT(YYYYMM) FOR YYYYMM IN (' + STUFF(REPLACE(#columns, ', p.[', ',['), 1, 1, '') + ')
) AS p;';
EXEC sp_executesql #sql;
SELECT *
FROM ##GlobalTemp
However this can cause issues with naming clashes if the code is ever executed concurrently.
It is possible to use a local temp table but the code is more involved as it involves creating a temp table at the upper scope and then using dynamic SQL to alter it to the dynamically determined schema before inserting into it.
CREATE TABLE #T
(
Dummy INT
);
SET #sql = 'ALTER TABLE #T ADD Dummy2 INT' + REPLACE(REPLACE(#columns, 'p.', ''), ']', '] int') + ';
ALTER TABLE #T DROP COLUMN Dummy, Dummy2;'
EXEC (#sql);
SET #sql = N'
INSERT INTO #T
SELECT ' + STUFF(#columns, 1, 2, '') + '
FROM
(
SELECT p.YYYYMM FROM #MY_DT_CTE AS p
) AS j
PIVOT
(
COUNT(YYYYMM) FOR YYYYMM IN (' + STUFF(REPLACE(#columns, ', p.[', ',['), 1, 1, '') + ')
) AS p;';
EXEC sp_executesql #sql;
SELECT *
FROM #T