SQL Dynamic Pivot Table Column Order - sql-server

I have a dynamic pivot table in ms sql server.
The column names are dates and appear in random order.
I would like to order the dates(columns) so they appear chronologically, the oldest being first and the most recent being last so I can trend the data by date.
I cannot figure out how to order the columns.
The date variable name is chartaccessdate.
Any help is appreciated.
Here is my code
declare #columnnames nvarchar(max)=''
declare #sql nvarchar(max)=''
select #columnnames += quotename(chartaccessdate) + ','
from (select distinct chartaccessdate from #temp ) as s
set #columnnames=left(#columnnames,len(#columnnames)-1)
set #sql=
'select * from (
select --phase,
unit,OccupationCode occode
,OccupationCode , chartaccessdate from #temp
) as a
Pivot
( count(OccupationCode)
FOR [chartaccessdate] IN (
'+#columnnames +
'
-- "2021-08-23"
--,"2021-08-24"
--,"2021-08-21"
--,"2021-08-22"
) )as pvt '
execute sp_executesql #sql

Rather than SELECT DISTINCT, one quick option would be:
select top 1000 chartaccessdate from #temp group by chartaccessdate order by 1

Related

How do I use the results of one query as the selected columns for another query?

I have a table (DataImportTable) that contains column names of the MainDataTable as its records - please see image:
Target Column Table
I would like to use the above-mentioned column names in a query to look only them up from my MainDataTable.
The query that obviously doesn't work, however can explain what I am trying to achieve, can be seen below:
select (select TargetColumn from DataImportTable) from MainDataTable
I hope this makes sense and that someone can be of assistance.
Thank you in advance!
You could do something like this:
declare #query varchar(max);
declare #columns varchar(max);
set #columns = (select TargetColumn + ', ' from DataImportTable for xml path(''));
set #query = 'select ' + left(#columns, len(#columns) -1) + ' from MainDataTable';
exec(#query);
First #columns is constructed as the values of the TargetColumn, comma-separated (with a trailing comma). Then, the columns are used to construct a query (the left-thing removes the trailing comma), which is in turn executed.
Use Dynamic SQL to get just the columns that are present in other table
Select row_number() over( order by TargetColumn ) as RowNumber,TargetColumn into
#temp from DataImportTable where TargetColumn is not null
Declare #Columnslist varchar(max),#i int
set #i = 1
while #i<= (select Count(*) from #temp)
begin
(SELECT #Columnslist = isnull(#Columnslist,'')+'['+(select TargetColumn from #temp
where RowNumber = #i)+'],')
set #i = #i + 1;
end
SELECT #Columnslist = LEFT(#Columnslist, LEN(#Columnslist) - 1)
Declare #select_cmd varchar(max)
set #select_cmd='select '+#Columnslist +' From MainDataTable'
EXEC(#select_cmd);
this answer makes it even simpler
exec('select '+(select Stuff((select ','+TargetColumn from DataImportTable
for xml path('')),1,1,''))+' From MainDataTable')
try select (select TargetColumn from DataImportTable) as TargetColumn from MainDataTable
What's wrong with this MySQL query? SELECT * AS `x`, how to use x again later?

Dynamic Pivot SQL in the Common Table Expression (CTE)

I am trying to Pivot a result of a CTE. Due to the privacy laws i cannot put my query and resultset here but the example looks like the below:
WITH CTE1
AS ( select ....)
,CTE2
AS (Select...)
,CTE3
as (Select...)
Below is the result of my CTE2:
and i want the result as
The main issue i am having here is to pivot the resultset with multiple and dynamic Pivot columns between CTE2 and CTE3 as i need to use the Pivot data in CTE3. Is there any solution without changing the CTE's to TempTable? Any help will be appreciated.
I think it's going to be something like this.
Dynamic Pivot:
DECLARE #query VARCHAR(4000)
DECLARE #years VARCHAR(2000)
SELECT #years = STUFF(( SELECT DISTINCT'],[' + [factor_label]
FROM [TEMP_lacp_factors]
ORDER BY '],[' + [factor_label]
FOR XML PATH('')
), 1, 2, '') + ']'
SET #query =
'SELECT * FROM
(
SELECT [date_],[issue_id],[cusip],[Factor_value],[factor_label]
FROM [TEMP_lacp_factors]
)t
PIVOT (MAX([factor_value]) FOR [factor_label]
IN ('+#years+')) AS pvt'
EXECUTE (#query)
Dynamic Pivot and Select Into:
-- Drop the table; you create it dynamically
Drop Table tempTable
--Start creating all objects for Dyanmic Pivot
DECLARE #query VARCHAR(4000)
DECLARE #years VARCHAR(2000)
SELECT #years = STUFF(( SELECT DISTINCT'],[' + [factor_label]
FROM [TEMP_lacp_factors]
ORDER BY '],[' + [factor_label]
FOR XML PATH('')
), 1, 2, '') + ']'
SET #query =
-- Objects that are created above, are put into the table you are about to create below
'SELECT * INTO tempTable FROM (SELECT * FROM
(
SELECT [date_],[issue_id],[cusip],[Factor_value],[factor_label]
FROM [TEMP_lacp_factors]
)t
PIVOT (MAX([factor_value]) FOR [factor_label]
IN ('+#years+')) AS pvt) X'
EXECUTE (#query)
-- Select everything from the dynamically created table ('tempTable') to see results
Select * from tempTable
I'm not 100% sure what you are doing, so it's just a best guess.

sql server 2008 pivot more than one column and dynamic column

I have two tables. I write a query. Date is dynamic. I can select any date. `
select a.MP,a.CP,a.Frequency,a.Time,CONVERT(varchar(12),b.date,101) as
EntryDate,b.actualtime from mpcp a, DailyData b
where a.UserID=1 and a.MpCpId=b.MpCpId and
CONVERT(varchar(12),b.EntryDate,101) between
CONVERT(varchar(12),GETDATE()-5,101) and
CONVERT(varchar(12),GETDATE()+25,101)`
Output
But i want output like
Assuming that i am storing your result in one temp table and imaging data i created one data for your requirement
try this one whether it is useful or not
create table #piv
(
mp varchar(10),
cp varchar(10),
freq varchar(10),
time int,
entryd date,
acuralize int
)
insert into #piv values
('don','asper','da',30,getdate(),0),
('dwm','donl','da',10,getdate(),3),
('qar','qpr','da',15,getdate(),5),
('qar','qpr','da',15,'01-16-17',5),
('qar','qpr','da',15,'01-15-17',5),
('qar','qpr','da',15,'01-16-17',5)
SELECT * FROM #piv
Declare #SQL varchar(max) = Stuff((Select Distinct ',' + QuoteName(entryd) From #piv Order by 1 For XML Path('')),1,1,'')
Select #SQL = '
Select *,' + #SQL + '
From #piv
Pivot (max(time) For [entryd] in (' + #SQL + ') ) p'
Exec(#SQL);
You can create a dynamic pivot. A good example is available on this link.
Good Luck !
DECLARE #cols VARCHAR(max),#sql VARCHAR(max)
SELECT #cols=ISNULL(#cols+',[','[')+ CONVERT(VARCHAR,a.EntryDate,101)+']'
FROM mpcp a, DailyData b
where a.UserID=1 and a.MpCpId=b.MpCpId and DATEDIFF(d,GETDATE(),b.EntryDate) BETWEEN -5 AND 25
GROUP BY a.time
SET #sql='
SELECT * FROM (
SELECT a.MP,a.CP,a.Frequency,a.Time,CONVERT(varchar(12),b.date,101) AS EntryDate,b.actualtime
FROM mpcp a, DailyData b
WHERE a.UserID=1 and a.MpCpId=b.MpCpId and where a.UserID=1 and a.MpCpId=b.MpCpId and DATEDIFF(d,GETDATE(),b.EntryDate) BETWEEN -5 AND 25
) AS t
PIVOT (MAX(actualtime) FOR EntryDate IN ('+#cols+') )'
EXEC(#sql)

How to select distinct values and have the differences as seperate columns in the same table

I have a one to many relationship between Course and Facilitator. The foreign key is in the Course table. How do I select a facilitator as distinct and have its multiple course IDs as columns next to the facilitator.
SELECT dbo.Facilitator.Fac_ID, dbo.Facilitator.Fac_Name, dbo.Course.Course_ID
FROM dbo.Course
RIGHT JOIN dbo.Facilitator ON dbo.Course.FK_Facilitator = dbo.Facilitator.Fac_ID
order by dbo.Facilitator.Fac_Name asc
returns:
instead, I want:
For pivoting, the column names should be defined. In your case you you do not have such a column name, as per your question. So we create sample column names like 1,2 etc.
First of all, get the column names for pivot
DECLARE #cols NVARCHAR (MAX)
SELECT #cols = COALESCE (#cols + ',[' + COLUMNNAME + ']', '[' + COLUMNNAME + ']')
FROM
(
-- Generates random column names numerically from 1,2 etc
SELECT DISTINCT CAST(ROW_NUMBER() OVER(PARTITION BY ID ORDER BY (SELECT 0))AS VARCHAR(4))COLUMNNAME
FROM #TEMP
) PV
ORDER BY CAST(COLUMNNAME AS INT)
Now pivot the result. I have written the logic inside.
DECLARE #query NVARCHAR(MAX)
SET #query = '-- This outer query forms your pivoted result
SELECT * FROM
(
-- Source data for pivoting
SELECT ID,NAME,VALUE,
CAST(ROW_NUMBER() OVER(PARTITION BY ID ORDER BY (SELECT 0))AS VARCHAR(4)) COLUMNNAME
FROM #TEMP
) x
PIVOT
(
--Defines the values in each dynamic columns
MIN(VALUE)
-- Get the names from the #cols variable to show as column
FOR COLUMNNAME IN (' + #cols + ')
) p
ORDER BY NAME;'
EXEC SP_EXECUTESQL #query
Click here to view result

Create table on SQL Server from dynamic pivot results

Is there a way to directly store the results of a dynamic pivot query into a fixed table? As the result is dynamic I can't create the table by specifying the columnnames and methods like "create table MyTable as (pivot select statement)" seem to fail on SQL server ("Incorrect syntax near the keyword 'AS'").
I have tried to format the SQL below to get a SELECT - INTO - FROM structure but failed to do so. Any help is obviously greatly appreciated!
The SQL used for the pivot is (build thanks to this great website!):
declare #pivot varchar(max), #sql varchar(max)
create table pivot_columns (pivot_column varchar(100))
insert into pivot_columns
select distinct DateField from MyTable order by 1
select #pivot=coalesce(#pivot+',','')+'['+pivot_column+']'from pivot_columns
set #sql = 'SELECT * FROM (select DateField, RefCode, SumField from MyTable) p
PIVOT
(sum(SumField) FOR DateField IN ( ' + #pivot + ') )
AS pvl'
drop table pivot_columns
exec (#sql)
Unless I am not following what you are trying to do you should be able to add the INTO mynewTable to your sql that you are going to execute and you should get the new table.
declare #pivot varchar(max), #sql varchar(max)
create table pivot_columns (pivot_column varchar(100))
insert into pivot_columns
select distinct DateField from MyTable order by 1
select #pivot=coalesce(#pivot+',','')+'['+pivot_column+']'from pivot_columns
set #sql = 'SELECT * INTO mynewTable FROM (select DateField, RefCode, SumField from MyTable) p
PIVOT
(sum(SumField) FOR DateField IN ( ' + #pivot + ') )
AS pvl'
drop table pivot_columns
exec (#sql)
I just test creating a new table in the following script and it gives me a new table that is in the DB for use:
create table t
(
[month] int,
[id] nvarchar(20),
[cnt] int
)
insert t values (4,'TOTAL',214)
insert t values (5,'TOTAL',23)
insert t values (6,'TOTAL',23)
insert t values (4,'FUNC',47)
insert t values (5,'FUNC',5)
insert t values (6,'FUNC',5)
insert t values (4,'INDIL',167)
insert t values (5,'INDIL',18)
insert t values (6,'INDIL',18)
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(month)
FROM t
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT *
INTO tabletest from
(
select month, id, cnt
from t
) x
pivot
(
sum(cnt)
for month in (' + #cols + ')
) p '
execute(#query)
drop table t

Resources