Dynamic PIVOT query - How to save it in SQL Server? - sql

I had to built a dynamic PIVOT in SQL Server as described in this article using the following script:
DECLARE #DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE #ColumnName AS NVARCHAR(MAX)
--Get distinct values of the PIVOT Column
SELECT #ColumnName= ISNULL(#ColumnName + ',','')
+ QUOTENAME(Course)
FROM (SELECT DISTINCT Course FROM #CourseSales) AS Courses
--Prepare the PIVOT query using the dynamic
SET #DynamicPivotQuery =
N'SELECT Year, ' + #ColumnName + '
FROM #CourseSales
PIVOT(SUM(Earning)
FOR Course IN (' + #ColumnName + ')) AS PVTTable'
--Execute the Dynamic Pivot Query
EXEC sp_executesql #DynamicPivotQuery
It works great and it returns a dynamic table as expected.
However, I would like to be able to select it in an other query but can not find a proper way to do so:
A view does not work as it does not accept variables
A table valued function does not work as I don't know in advance the structure of the output table
A stored procedure does not work as I can not use it in a SELECT query
What would be the best solution to save this dynamic pivot query and be able to SELECT it afterwards?
Thank you
Sylvain

Oh. You can use temp table, my friend. The first, check the exists of temp table. And remember drop it at the end of query.

You could try to use the stored procedure and in that sp use the SELECT INTO in the dynamic pivot query and store in a temporary table (#myDynamicPivot).
Then you can use the temporary table in your next selects statements. Make sure you drop your table after using it.
Edit
I would consider moving that data that the pivot table is created against to a data warehouse and create an analysis database over it. This way you can query using the dimensions and the data will be much faster and it will be more optimized for storage and query.

Related

Perform query on multiple tables

I need to apply the following query to 60+ tables:
UPDATE variable_table_name ab
SET elem_nr = ef.elem_nr
FROM ga_mit_elemnr ef
WHERE (ab.elem_nr NOT IN
(SELECT elem_nr
FROM strassenelemente cd)
OR ab.elem_nr IS NULL)
AND St_within(ab.geom, ef.geom)
Is there a way to automate this in PostgreSQL?
As far as I am aware it is not possible to do this in Plain SQL, however you could use PL/pgSQL to execute the query as dynamic command in a for loop and run this query against your 60+ tables. You can read about Pl/pgSQL here: https://www.postgresql.org/docs/9.6/plpgsql.html
Depending on your requirements you could also use other programming languages such as Python to dynamically execute SQL-statements as string.
After understanding the case, I would suggest using postgres partitioning mechanism
I.e have a master table and 60+ partitions, each partition will be attached to the master, and on ALTER TABLE you alter only the master table schema, and all the rest will be updated as well
Something like this..?
DECLARE #sql NVARCHAR(max)
SELECT #sql = N' '+ String_agg(Concat(N'
UPDATE ', CONVERT(NVARCHAR(max), Quotename(col_table_name)), N'
SET column1 = value1, column2 = value2...., columnN = valueN
WHERE [condition];'), N'' + CHAR(13) + CHAR(13))
FROM information_schema.tables
WHERE [condition]
EXEC (#sql)
Once you get the query, you can check the query by using the SELECT statement.
SELECT (#sql)
If the query is okay, then you can execute it.
EXEC (#sql)
Example: https://data.stackexchange.com/stackoverflow/query/1011376/

I want to generate SQL query output like screenshot

I am getting data like below screenshot using select VendorShortName,BasePrice,convert(varchar, ModifiedDate,101) as date from prices where barcode='8712566383849'
Now for generating the graph, I need data like below screenshot.
Can anyone help me?
You can easily do this by using PIVOT. Here is example how you will get that. Firt Image will show you simple PIVOT Query and how you achieve that.
Second Image Will show you dynamic Query generation - which might be more helpful as based on your image it seems you require to generate dynamic columns
so please refer second image for the same.
Based on query i have created below snippet - see if it helps you.
DECLARE #DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE #ColumnName AS NVARCHAR(MAX)
--Get distinct values of the PIVOT Column
SELECT #ColumnName= ISNULL(#ColumnName + ',','')
+ QUOTENAME(vendorshortname)
FROM (select distinct vendorshortname from Prices) AS Prices
--Prepare the PIVOT query using the dynamic
SET #DynamicPivotQuery =
N'SELECT ModifiedDate, ' + #ColumnName + '
FROM (select VendorShortName,BasePrice,ModifiedDate from prices where barcode=''8712566383849'') As SourceTable
PIVOT
(avg(BasePrice)
FOR VendorShortName IN (' + #ColumnName + ')) AS PVTTable'
--Execute the Dynamic Pivot Query
EXEC sp_executesql #DynamicPivotQuery
Depending on the type of database, PIVOT is what you use in these cases. You will need to know the values of V1, V2 etc. or do dynamic SQL.
Traditionally though, this kind of manipulation is done at the client (graphing) side, not on the database because, as you are discovering, that transformed data is not a good fit to the relational model.

How to return data from stored procedure in a view SQL Server 2008

So i have this code:
DECLARE #DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE #ColumnName AS NVARCHAR(MAX)
--Get distinct values of the PIVOT Column
SELECT #ColumnName= ISNULL(#ColumnName + ',','')
+ QUOTENAME(period)
FROM (SELECT DISTINCT period FROM atbv_Accounting_OrdersDeliveries WHERE InvoiceNo IS NOT NULL) AS Periods
SET #DynamicPivotQuery =
N'SELECT ' + #ColumnName + '
FROM (SELECT
ArticleID, period, SUM(Amount) As Total
FROM atbv_Accounting_OrdersDeliveries
WHERE InvoiceNo IS NOT NULL
GROUP BY ArticleID, period
) AS T
PIVOT(SUM(TOTAL)
FOR period IN (' + #ColumnName + ')) AS PVTTable'
--Execute the Dynamic Pivot Query
EXEC sp_executesql #DynamicPivotQuery
I saved in i a stored procedure as i cannot declare variables in a view. Is there a way to call this procedure in a view? Note that column amount is dynamic as well :)
Thanks!
Try to use the Stored Procedure instead of a view.
If that isn't possible for any reason, you can create a SQL Server Agent Job that periodically fills a table using a stored procedure and the client than uses the "cached" data.
You can't have a dynamic view, what would be the point?
If you want to know how to share data from stored procedures then
How to Share Data between Stored Procedures
is a great text. If you want to understand dynamic SQL then I recommend
The Curse and Blessings of Dynamic SQL
by the same author, Erland Sommarskog. Both topics are too expansive for a simple answer on Stack Overflow.

SQL Server - select into from statement?

I have this query in SQL Server:
select column
from table_53;
Now, I want to get this 53 from another table, so what I want to do is something like this:
select column
from table_(select id from table2);
Is there any way to do this in SQL Server?
This is definitely not the way SQL thinks and works. Maybe your suggested approach can be mimicked by way of writing stored procedures in which you create SQL-statements which are then evaluated. However, this will not be very efficient.
A better approach would be to store the values of all your individual separate tables into one master table and mark them in a separate column tblid with their number (e.g. 53). Then you can always filter them from this master table by looking for this tblid.
You need dynamic sql query here.
declare #sqlQuery = 'select column
from table_(';
set #sqlQuery = #sqlQuery + 'select id from table2)';
EXEC (#sqlQuery)
Note :- One of cons of using dynamic sql query is sql injection. I would suggest to have better table structure or try to used parameterized query.
Yes, you can, but using something like this:
DECLARE #ID INT;
DECLARE #QUERY NVARCHAR(MAX);
SELECT #ID = ID FROM TABLE_2;
--IF #ID EQUALS 53 THEN
SET #QUERY = 'SELECT COLUMN FROM TABLE_' + CAST(#ID AS NVARCHAR(10));
-- #QUERY EQUALS TO 'SELECT COLUMN FROM TABLE_53'
EXEC (#QUERY);

Creating a dynamic table from dynamic SQL

First of all I'm using ms SQL server 2012. I' trying to use a table based on a string value passed in as a string into a procedure. I found out that you can't use strings are table names when writing a query so I'm trying to find a way around that. The only lead I'm kind of onto is using dynamic SQL which I also am not sure how to make work. Here is what I have:
DECLARE #q AS NVARCHAR(MAX)
SET #q = 'SELECT * FROM ' + #tableName
DECLARE #tableCopy AS EXECUTE(#q)
How can I get the executed #q into #tableCopy? Or is there a better way to access my table when all I know is the tables name as a string?
You can create the temporary table and then insert into that table inside the dynamic sql. There's an example here:
http://smehrozalam.wordpress.com/2009/10/14/t-sql-using-result-of-a-dynamic-sql-query-in-a-variable-or-table/
Unfortunately, you would need to know the schema. The following does not work:
declare #query varchar(max) =
'select * into #t from table'
EXEC(#query)
select * FROM #t