I have the following query and I need to store it as a view, I am lost and any help appreciated. I am using Microsoft SQL Server 2016. I have been wrestling with returning the data in a form I need using online guides but now I have it but I am unable to convert to a view.
DECLARE #T AS TABLE(y INT NOT NULL PRIMARY KEY);
DECLARE
#cols AS NVARCHAR(MAX),
#y AS INT,
#sql AS NVARCHAR(MAX);
-- Construct the column list for the IN clause
SET #cols = STUFF(
(SELECT N',' + QUOTENAME(y) AS [text()]
FROM (SELECT DISTINCT AttName AS y FROM vwObjectAttributesValuesAsRows) AS Y
ORDER BY y
FOR XML PATH('')),
1, 1, N'');
-- Construct the full T-SQL statement
-- and execute dynamically
SET #sql = N'SELECT *
FROM (SELECT ObjectID, ObjectName, AttName, value
FROM vwObjectAttributesValuesAsRows
) AS D
PIVOT(Max(value) FOR AttName IN(' + #cols + N')) AS P;';
EXEC sp_executesql #sql;
GO
Related
Im new to Stack overflow and SQL and I'm trying to replicate a function in Microsoft Power Query to use in SQL instead.
I know how to Unpivot and keep 1 Column in SQL and then had to reference all the other columns by name to make the unpivot.
Now I need to Keep 3 ID columns and Unpivot the rest of the columns
(This table has 355 columns right now and will change)
Can anyone help me with this?
This is the furthest I got (Thanks to RAV DBLearning on Youtube), but I cant seem to find a way to Convert the columns types to 1 type.
DECLARE
#SQLSTRING NVARCHAR(MAX),
#COLUMNLIST NVARCHAR(1000) = ''
SELECT
#COLUMNLIST = #COLUMNLIST + QUOTENAME(NAME) + ','
FROM
sys.columns
WHERE
OBJECT_ID = OBJECT_ID('xp.XPROPERTYVALUES') AND
--COLUMN_ID NOT IN(1,2,3)
COLUMN_ID IN(452,453,454)
SELECT
#COLUMNLIST = LEFT(#COLUMNLIST,LEN(#COLUMNLIST)-1)
SET
#SQLSTRING =
'
SELECT
upv.id,
upv.item_id,
upv.itemtype_id,
upv.X_Category,
upv.X_Values
FROM
xp.XPROPERTYVALUES
UNPIVOT
(
X_Values FOR X_Category
IN
(' + #COLUMNLIST + ')
) AS upv
'
PRINT
(#SQLSTRING)
EXECUTE
sp_executesql #SQLSTRING
It just needs a source query.
And you can re-use the calculated column list for that.
DECLARE #SQLSTRING NVARCHAR(MAX),
#COLUMNLIST NVARCHAR(MAX);
DECLARE #TABLENAME VARCHAR(30) = 'xp.XPROPERTYVALUES';
SELECT #COLUMNLIST = CONCAT(#COLUMNLIST + ', ', QUOTENAME(NAME))
FROM sys.columns
WHERE OBJECT_ID = OBJECT_ID(#TABLENAME)
AND LOWER(NAME) NOT LIKE '%id';
SET #SQLSTRING = N'SELECT upv.id
, upv.item_id, upv.itemtype_id
, upv.X_Category, upv.X_Values
FROM
(
SELECT id, item_id, itemtype_id,
'+ #COLUMNLIST + N'
FROM '+ #TABLENAME +N'
) src
UNPIVOT
(
X_Values FOR X_Category IN (' + #COLUMNLIST + N')
) upv';
-- SELECT #SQLSTRING;
EXECUTE sp_executesql #SQLSTRING;
db<>fiddle here
I have a shop order table with the Item code, description ReleaseDate and Required quantity.
How to query in a pivot table format in such a way that the results will be pivoted using Year+Month of [ReleaseDate] in sorting order from oldest date to latest date. Using the Year+Month as a column.
This is my query but it fails.
--Declare necessary variables
DECLARE #SQLQuery AS NVARCHAR(MAX)
DECLARE #PivotColumns AS NVARCHAR(MAX)
--Get unique values of pivot column
SELECT #PivotColumns = COALESCE(#PivotColumns + ',','') + QUOTENAME([YEARMONTH])
FROM (SELECT DISTINCT CONVERT(char(6), cast([releaseddate] as date), 112 ) as [YEARMONTH] FROM [dbo].[ShopOrder]) as PivotQuery
SELECT #PivotColumns
--Create the dynamic query with all the values for
--pivot column at runtime
SET #SQLQuery =
N'SELECT ItemCode, ' + #PivotColumns + '
FROM [dbo].[ShopOrder]
PIVOT( SUM(RequiredQty)
FOR [releaseddate] IN (' + #PivotColumns + ')) AS P'
SELECT #SQLQuery
--Execute dynamic query
EXEC sp_executesql #SQLQuery
This is the original record
Results query must be like this
Here I have tried to execute the pivot with your provided data.
Query
Select
[ItemCode],
[Description],
[2017/8],
[2017/9]
from
(
select cast(year(ReleasedDate) as nvarchar)+'/'+cast(month(ReleasedDate) as nvarchar) as ReleasedDate,ItemCode,Description,RequiredQty
from shoporder) as PivotData
Pivot
(
sum(RequiredQty) for ReleasedDate in
([2017/8],[2017/9])) as Pivoting
order by ItemCode
Output:
Fiddle
You are not pivoting correctly and the column names should be generated in a single string. Try this:
CREATE TABLE ShopOrder (ItemCode VARCHAR(100),[Description] VARCHAR(100),ReleaseDate DATE, RequiredQty INT)
GO
INSERT INTO ShopOrder
VALUES
('A','SLEEVE NUT','08/01/2017',19200)
,('A','SLEEVE NUT','08/02/2017',18000)
,('A','SLEEVE NUT','09/01/2017',17000)
,('B','STARTER','08/03/2017',10000)
,('B','STARTER','08/04/2017',18000)
,('B','STARTER','09/15/2017',16000)
DECLARE #SQLQuery AS NVARCHAR(MAX)
DECLARE #PivotColumns AS NVARCHAR(MAX)
SET #PivotColumns = STUFF(( SELECT DISTINCT ',[' + CONVERT(char(6), cast(ReleaseDate as date), 112 ) + ']'
FROM ShopOrder
ORDER BY ',[' + CONVERT(char(6), cast(ReleaseDate as date), 112 ) + ']'
FOR XML PATH('')),1,1,'')
SET #SQLQuery =
N'
SELECT ItemCode,'+ #PivotColumns + '
FROM (SELECT ItemCOde,CONVERT(char(6), cast(ReleaseDate as date),112) ReleaseDate, RequiredQty
FROM ShopOrder) AS T
PIVOT( SUM(RequiredQty)
FOR ReleaseDate IN ('+#PivotColumns+')) AS P
'
SELECT #SQLQuery
--Execute dynamic query
EXEC sp_executesql #SQLQuery
I'm trying to transpose a simple table from rows to columns with two string variables. I went trough several examples from the web without success. The number of rows will vary so I need to transpose the table dynamically. The following code at least does not produce an error but does not generate the result!
The sample table
create table #Encabezado
(
NodeName nvarchar(100),
NodeValue nvarchar(100)
)
INSERT INTO #Encabezado (NodeName, NodeValue) VALUES
('RUTEmisor','88888888-8'),
('RznSoc','EMPRESA DE PRUEBA'),
('GiroEmis','Informatica'),
('Acteco','1'),
('CdgSIISucur','59529595'),
('DirOrigen','Teatinos 120'),
('CmnaOrigen','Santiago'),
('CiudadOrigen','Santiago')
GO
The unpivot code
DECLARE #colsUnpivot AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #colsUnpivot
= stuff((select ','+quotename(C.column_name)
from information_schema.columns as C
where C.table_name = '#Encabezado' and
C.column_name like '%Name'
for xml path('')), 1, 1, '')
set #query
= 'select NodeName,
Nodevalue
from #Encabezado
unpivot
(
NodeName
for NodeName in ('+ #colsunpivot +')
) u'
exec sp_executesql #query;
Any help would be appreciated
Sequelspear once said : "To Pivot or UnPivot, That's the question."
declare #cols NVARCHAR(MAX) = stuff((select ','+quotename(Nodename) from #Encabezado group by Nodename for xml path('')),1,1,'');
declare #query NVARCHAR(MAX) = 'select * from #Encabezado pivot (max(NodeValue) for NodeName IN ('+ #cols +')) pvt';
exec sp_executesql #query;
To Dynamically Pivot
Declare#Cols AS NVARCHAR(MAX),#SQL AS NVARCHAR(MAX);
Set #Cols = Stuff((Select Distinct ',' + QuoteName(NodeName)
From #Encabezado
For XML Path(''), Type
).value('.', 'varchar(max)'),1,1,'')
Set #SQL = 'Select * From #Encabezado
Pivot (
max(NodeValue)
For [NodeName] in (' + #Cols + ')
) p '
Exec (#SQL)
Returns
Now, to unpivot, consider the following:
Declare #User table (ID int,Active bit,First_Name varchar(50),Last_Name varchar(50),EMail varchar(50))
Insert into #User values
(1,1,'John','Smith','john.smith#email.com'),
(2,0,'Jane','Doe' ,'jane.doe#email.com')
Declare #XML xml = (Select * from #User for XML RAW)
Select ID = r.value('#ID','int')
,Active = r.value('#Active','bit')
,Item = attr.value('local-name(.)','varchar(100)')
,Value = attr.value('.','varchar(max)')
From #XML.nodes('/row') as A(r)
Cross Apply A.r.nodes('./#*') AS B(attr)
Where attr.value('local-name(.)','varchar(100)') not in ('ID','Active')
Returns
I have a dynamic stored procedure which runs in SSMS. Is it possible to convert this proc into a function so when ever I do
exec function stored.proc
I can run this from my ETL?
My query as below -
create procedure dbo.bear_load
as
set nocount on;
Declare #cols as NVARCHAR(MAX), #query as NVARCHAR(MAX), #Result as NVARCHAR(MAX)
select #cols = STUFF((SELECT ',' + QUOTENAME(FIELD_NAME)
from bear_crossjoin
group by Field_Name, FIELDNUMBER
order by FIELDNUMBER
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = N'SELECT ' + #cols + N'
from
(
select substring, Field_Name,
rn = row_number() over(partition by field_name order by fieldnumber)
from bear_crossjoin
) x
pivot
(
max(substring)
for Field_Name in (' + #cols + N')
) p '
set #Result= ' select ' + #query
EXEC (#query)
GO
exec dbo.bear_load
Any help very much appreciated.
Arun
I am working on a project with SSRS and Rockwell Software's RSView32. Basically this software project logs manufacturing data to individual tables as such:
One table (Machine1_TagTable) has Tag names which describe the data as such: TagName, TagIndex. The name provides a human-understandable reference to the information contained in a second table. Example : Part Number, 1
The second table (Machine1_FloatTable) contains raw data with nothing more than a timestamp, TagIndex and value.
Example : 2013-12-10 15:44:11.322, 1, 12345(value)
I have a dynamic pivot which works for ONE table; however, I would like to use a variable parameter passed from SSRS to select both the TagTable and FloatTable.
This works with the Machine1_FloatTable as part of the dynamic statement, but not in the XML path building. I understand this is a scope issue, so I'm looking for creative ways to allow me to pass the table names from SSRS into this stored procedure.
Here's what I have now:
DECLARE #FLOATTABLE NVARCHAR(MAX), #TAGTABLE NVARCHAR(MAX), #startdate NVARCHAR(MAX),
#enddate NVARCHAR(MAX), #cols as NVARCHAR(MAX), #query as NVARCHAR(MAX)
SET #TAGTABLE ='dbo.Machine1_TagTable'
SET #FLOATTABLE = 'dbo.Machine1_FloatTable'
SELECT #cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(CONVERT(VARCHAR,TagName),'"')
FROM #tagtable
FOR XML PATH('')),1,1,'')
Set #query = 'SELECT DISTINCT DateAndTime, Millitm, ' + #cols + ' FROM ( select
T.DateAndTime, T.Millitm, N.TagName, T.Val from ' + #FLOATTABLE + ' T LEFT JOIN ' +
#TAGTABLE + ' N ON T.TagIndex=N.TagIndex WHERE T.DateAndTime Between '''+ #startdate +
''' AND '''+ #enddate +''') x PIVOT (MAX(Val) for TagName IN (' + #cols + ')) p'
PRINT (#query)
Any help or suggestions would be greatly appreciated. Thanks!
Well, it's possible, if I understand your question. You have to build a dynamic SQL string, and execute that to populate #cols.
declare #string nvarchar(MAX)
set #String = 'SELECT STUFF((SELECT DISTINCT '','' + QUOTENAME(CONVERT(VARCHAR,ActualDate),'
+ '''"'') FROM ' + #TAGTABLE + ' FOR XML PATH ('''')),1,1,'''')'
EXECUTE sp_executeSQL #String, #Cols OUTPUT
print #cols
It's pretty hacky, but I think it should work.