Workaround DECLARE statement in View - sql

I have the following which I would like to be a View, but the Declare statement is not allowed apparently.
What is the best solution/work-around to this problem?
I'm using SQL Server. I have tried many other solutions (Stored Procedures, Table-Values Functions), but I think the combination of Dynamic SQL is complicating the matter and I haven't been able to get anything working.
DECLARE #cols AS NVARCHAR(MAX),
#colsAlias AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
select #cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(MeasurementTypeID)
FROM dbo.Measurements
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SELECT #colsAlias = STUFF((SELECT DISTINCT ',' + QUOTENAME(dbo.Measurements.MeasurementTypeID) + ' AS ' + QUOTENAME(dbo.MeasurementTypes.MeasurementType)
FROM dbo.Measurements INNER JOIN dbo.MeasurementTypes ON dbo.Measurements.MeasurementTypeID = dbo.MeasurementTypes.MeasurementTypeID
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'')
SET #query = 'SELECT NeuronID, ' + #colsAlias +' FROM
(
SELECT MeasurementName, MeasurementValue, NeuronID, MeasurementTypeID
FROM dbo.Measurements
) x
PIVOT
(
MIN(MeasurementValue) FOR MeasurementTypeID IN (' + #cols + ')
) AS p'
EXECUTE(#query)

Related

Summing multiple dynamically declared variables (fast)

I'm developing a program where I have multiple columns which I need to show the sum of to anEnd-user. These columns are assigned in the table ColumnTest in the column ColumnNames and their names can be changed by the user. Therefore I need to look up all the column names in ColumnTest\ColumnNames and afterwards sum all values regarding these columnnames from the outputtable.
I have previously used this script where I get all the columnnames in #cols like this [col1].[col2].[col3] and so on, but when I try to run the query I'm not able to sum these columns using '+ #cols + '. When I run this I get the following error: The SUM function requires 1 argument(s). Is there a viable option to do this procedure, without compromising the loading-time substantially?
DECLARE
#cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
SELECT #cols = STUFF((SELECT distinct ',' + QUOTENAME(c.ColumnNames)
FROM ColumnTest c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)') ,1,1,'')
set #query =
'
SELECT
ID
,SUM('+ #cols + ')
FROM Output_table
GROUP BY
ID
'
execute(#query);
Try this,
DECLARE
#cols AS NVARCHAR(MAX)='',
#query AS NVARCHAR(MAX);
SELECT #cols += 'SUM('+ColumnNames+') as ['+ColumnNames+'],'
from
(
SELECT distinct ColumnNames FROM ColumnTest
)A
SELECT #cols=LEFT(#cols,LEN(#cols)-1)
set #query =
'
SELECT ID,'+ #cols + '
FROM Output_table
GROUP BY ID
'
execute(#query);
or if you want addition of all column values you can use below query
DECLARE #cols AS NVARCHAR(MAX)='',
#query AS NVARCHAR(MAX);
SELECT #cols += ''+ColumnNames+'+'
FROM
(
SELECT DISTINCT ColumnNames FROM ColumnTest
)A
SELECT #cols=LEFT(#cols,LEN(#cols)-1)
set #query =
'
SELECT ID,SUM('+ #cols + ')
FROM Output_table
GROUP BY ID
'
execute(#query);
You can not use comma separated like ','
You can use '+'
Try this
DECLARE
#cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
SELECT #cols = STUFF((SELECT distinct '+' + QUOTENAME(c.ColumnNames)
FROM ColumnTest c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)') ,1,1,'')
set #query =
'
SELECT
ID
,SUM('+ #cols + ')
FROM Output_table
GROUP BY
ID
'
execute(#query);

Combine two pivot tables SQL Server

I am trying to cross join two pivot tables.
--First Pivot table query gets columns of drug_names and produces the row value
--of the drug_id.
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
Select #cols = STUFF((SELECT ',' + QUOTENAME(drug)
from _app_drugs
group by drug, drug_id,order_number
order by order_number
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = N'SELECT ' + #cols + N' from
(
select drug_id, drug
from _app_drugs
) x
pivot
(
max(drug_id)
for drug in (' + #cols + N')
) p'
exec sp_executesql #query;
--The second pivot table simply gets the signature_labels and displays the label name in the column and displays the label_id as the row value.
DECLARE #cols AS NVARCHAR(MAX),#scols as NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
Select #cols = STUFF((SELECT ',' + QUOTENAME(signature_label)
from _app_signature_labels
WHERE _app_signature_labels.isactive=1
group by signature_label_id, signature_label,ordernumber
order by ordernumber
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = N'SELECT ' + #cols + N' from
(
select signature_label_id,signature_label
from _app_signature_labels
) x
pivot
(
max(signature_label_id)
for signature_label in (' + #cols + N')
) p'
exec sp_executesql #query;
Now I just need to know how to combine these two pivot tables as one table... they don't have a common field and don't need one.
Can anybody help me with this one?
Thank you
You can execute two separate dynamic SQL statements into two global temp tables and then combine the result, like this:
IF object_id('tempdb..##tmpResult1') IS NOT NULL
BEGIN
DROP TABLE ##tmpResult1
END
IF object_id('tempdb..##tmpResult2') IS NOT NULL
BEGIN
DROP TABLE ##tmpResult2
END
DECLARE #cols AS NVARCHAR(MAX),
#cols2 AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX),
#query2 AS NVARCHAR(MAX)
Select #cols = STUFF((SELECT ',' + QUOTENAME(drug)
from _app_drugs
group by drug, drug_id,order_number
order by order_number
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = N'SELECT ' + #cols + N' INTO ##tmpResult1 from
(
select drug_id, drug
from _app_drugs
) x
pivot
(
max(drug_id)
for drug in (' + #cols + N')
) p'
exec sp_executesql #query;
--The second pivot table simply gets the signature_labels and displays the label name in the column and displays the label_id as the row value.
Select #cols2 = STUFF((SELECT ',' + QUOTENAME(signature_label)
from _app_signature_labels
WHERE _app_signature_labels.isactive=1
group by signature_label_id, signature_label,ordernumber
order by ordernumber
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query2 = N'SELECT ' + #cols2 + N' INTO ##tmpResult2 from
(
select signature_label_id,signature_label
from _app_signature_labels
) x
pivot
(
max(signature_label_id)
for signature_label in (' + #cols2 + N')
) p'
exec sp_executesql #query2;
SELECT * FROM ##tmpResult1 t1
INNER JOIN ##tmpResult2 t2 ON t1.ordernumber = t2.ordernumber
This is also a way to address this error when doing a large PIVOT query: Internal error: An expression services limit has been reached. Please look for potentially complex expressions in your query, and try to simplify them.

Generating expression string in SQL to add values of a column in pivot

I want to get this string for using in my other queries
#cols = 'ISNULL(myColumnName_value_1,0) + ISNULL(myColumnName_value_2,0) + ... + ISNULL(myColumnName_value_N,0)'
and myColumnName_value_1 ORmyColumnName_value_2 , ... which could be anything.
And my query is:
DECLARE #cols AS NVARCHAR(MAX)
SET #cols = STUFF((SELECT distinct ' + ISNULL(' + (c.myColumnName) +',0)'
FROM myTableName c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
print #cols
but I can't get what I want.
my desired output of print:
ISNULL(myColumnName_value_1,0) +
ISNULL(myColumnName_value_2,0) + ... +
ISNULL(myColumnName_value_N,0)
And ... because I don't know the name or number of columns.
Here is your modified query.
DECLARE #cols AS NVARCHAR(MAX)
SET #cols = STUFF((SELECT distinct ' + ISNULL(' + QUOTENAME(c.myColumnName) +',0)'
FROM myTableName c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,2,1,'')
print #cols

Dynamic pivot where clause

I have a dynamic pivot written as below, I need to add a where clause
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX),#uniqId varchar(50);
set #uniqId = 'IN0s3Z0n8z4v'
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(c.DisplayLabel)
FROM [dbo].[CountyCaseUserData] c where UniqueEntryId = #uniqId
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
print #cols
set #query = 'SELECT ' + #cols + '
from
(
SELECT UserInput, DisplayLabel,row_number()
over (partition by DisplayLabel order by CCId) AS No
from [dbo].[CountyCaseUserData] where UniqueEntryId = #uniqId
) x
pivot
(
max(UserInput)
for DisplayLabel in (' + #cols + ')
) p ';
execute(#query)
But when executing, I get a message
Must declare the scalar variable "#uniqId"
What am I missing here?
as what others pointed out,
change execute(#query)
to
exec sp_executesql #query, N'#uniqId varchar(50)', #uniqId

Dynamic Pivot Query with parameter

In the following query, the formid parameter is causing an error. I have tried using a static value in place of the formid parameter, in which case the query succeeds. Am I using improper syntax? This thread appear to solve the issue, but the syntax seems to be the same.
ALTER PROCEDURE [dbo].[customFormReport]
(
#formid int
)
AS
BEGIN
SET NOCOUNT ON
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(fieldname)
from FormResponse
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT FormID, FormSubmissionID,' + #cols + ' from
(
SELECT FormID, FormSubmissionID, fieldname, value
FROM FormResponse WHERE FormID = ' + #formid + '
) x
pivot
(
max(value)
for fieldname in (' + #cols + ')
) p '
execute(#query)
convert it to string,
CAST(#formid AS VARCHAR(25))