I am building a dynamic SQL statement
This my code
declare #TmpDRGs varchar(max)
set #TmpDRGs = 'CREATE TABLE #TmpDRGs ( ur_number varchar(10) '
declare #Temp1 as table (diagnosis varchar(10))
insert into #Temp1 (diagnosis)
select DISTINCT diagnosis
from PtsDiagnosis
order by diagnosis
update #Temp1
set #TmpDRGs = #TmpDRGs + ',[' + diagnosis + '] tinyint'
select #TmpDRGs
The output is
CREATE TABLE #TmpDRGs ( ur_number varchar(10) ,[X90] tinyint,[N73] tinyint,[P84] tinyint,[B08]...
I want them to be in order like this
CREATE TABLE #TmpDRGs ( ur_number varchar(10) ,[B08] tinyint,[N73] tinyint,[P84] tinyint,[X90]...
I used order by in the building #Temp1 table but still getting them in wrong order
I cannot order by the update statement
so how to put these columns in order?
Try the following:
DECLARE #B VARCHAR(MAX) = 'CREATE TABLE #B ( ur_number varchar(10),'
SELECT #B += STUFF((SELECT DISTINCT ',['+ CAST(diagnosis AS VARCHAR) + '] tinyint'
FROM PtsDiagnosis
ORDER BY diagnosis
FOR XML PATH('')),1,1,'')+')'
PRINT(#B)
Related
How can I convert rows into columns and create different name for each column?
create table #TempTable (InvoiceNum int,State varchar(2), ChargeName varchar(50), PercentageRate decimal(5,3), FlatRate decimal(5,2))
insert into #TempTable values (235736, 'AZ','Inspection & Policy Fee', NULL,250.00)
,(235736, 'AZ','Surplus Line Tax',0.03,NULL)
,(235736, 'AZ','Stamping Fee',0.002,NULL
)
I need something like that:
UPDATE:
Using example I was able to unpivot it but the result is not what I wanted to:
create table #TempTable (InvoiceNum int,State varchar(2), ChargeName varchar(50), PercentageRate decimal(5,3), FlatRate decimal(5,2))
insert into #TempTable values (235736, 'AZ','Inspection & Policy Fee', NULL,250.00)
,(235736, 'AZ','Surplus Line Tax',0.03,NULL)
,(235736, 'AZ','Stamping Fee',0.002,NULL)
--select * from #TempTable
Declare #SQL nvarchar(max),
#query nvarchar(max)
select #SQL = STUFF((SELECT ',' + QUOTENAME(ChargeName)
from #TempTable
group by ChargeName, InvoiceNum
order by InvoiceNum
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
--select #SQL
set #SQL = 'SELECT ' + #SQL + ' from
(
select PercentageRate, ChargeName
from #TempTable
) x
pivot
(
max(PercentageRate)
for ChargeName in (' + #SQL + ')
) p '
exec sp_executesql #SQL;
UPDATE:
Running below query gives me this:
Why ChargeName is not on the first row? I would expect to see it like this: What am I missing?
declare #TempTable table (InvoiceNum int,StateID varchar(2), ChargeName varchar(50), PercentageRate decimal(5,3), FlatRate decimal(5,2))
insert into #TempTable values (235736, 'AZ','Inspection & Policy Fee', NULL,250.00)
,(235736, 'AZ','Surplus Line Tax',0.03,NULL)
,(235736, 'AZ','Stamping Fee',0.002,NULL)
select
InvoiceNum,
ChargeName,
StateID,
PercentageRate,
FlatRate,
row_number() over (partition by InvoiceNum order by ChargeName) as RN
into #TempTable
from #TempTable #TempTable
DECLARE #DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE #ColumnName AS NVARCHAR(MAX)
--Get distinct values of the PIVOT Column
SELECT #ColumnName= ISNULL(#ColumnName + ',','')
+ QUOTENAME(RN)
FROM (SELECT DISTINCT RN FROM #TempTable) AS RN
--Prepare the PIVOT query using the dynamic
SET #DynamicPivotQuery =
N'SELECT InvoiceNum, ' + #ColumnName + '
FROM #TempTable
PIVOT(MAX(ChargeName)
FOR RN IN (' + #ColumnName + ')) AS PVTTable'
EXEC sp_executesql #DynamicPivotQuery
drop table #TempTable
I would just join the temp table multiple times as needed.
Given your #TempTable
SELECT T1.InvoiceNum,
Tax1_Jurisdiction = T1.State, Tax1_TaxType = T1.ChargeName, Tax1_Percent = T1.PercentageRate, Tax1_FixedRate = T1.FlatRate,
Tax2_Jurisdiction = T2.State, Tax2_TaxType = T2.ChargeName, Tax2_Percent = T2.PercentageRate, Tax2_FixedRate = T2.FlatRate,
Tax3_Jurisdiction = T3.State, Tax3_TaxType = T3.ChargeName, Tax3_Percent = T3.PercentageRate, Tax3_FixedRate = T3.FlatRate
FROM #TempTable T1
JOIN #TempTable T2 ON T1.InvoiceNum = T2.InvoiceNum
JOIN #TempTable T3 ON T1.InvoiceNum = T3.InvoiceNum
WHERE T1.ChargeName = 'Inspection & Policy Fee'
AND T2.ChargeName = 'Surplus Line Tax'
AND T3.ChargeName = 'Stamping Fee'
;
i have data in below format. this data is coming through SQL Query.
i want to show it in below format either by query or by rdlc report.
You need to use dynamic SQL to make it.
From your expected result you can try to follow thoes step to make it.
use row_number function make row number by Name, because we need to join base on that row_number.
get the use MAX and MIN to make row number calendar table. from 1 to max(rn). the table can let use outer join
declare a var #tables to make the OUTER JOIN execute SQL (each LEFT JOIN maen a group of Crew#).
declare a var #col to make column, which you want to select (Employee) from each table.
then use execute dynamic execute it.
look like this.
create table T
(
Name varchar(50),
Employee VARCHAR(50)
)
insert into T values ('Crew#1','TR123');
insert into T values ('Crew#1','311');
insert into T values ('Crew#2','DDD');
insert into T values ('Crew#2','12121');
insert into T values ('Crew#1','SDDAS');
insert into T values ('Crew#3','31114312');
insert into T values ('Crew#3','DD14124D');
insert into T values ('Crew#3','1214124121');
insert into T values ('Crew#3','SDD412AS');
DECLARE #tables AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX),
#col AS NVARCHAR(MAX);
SET #tables = STUFF((SELECT distinct ' LEFT JOIN ' + ' (SELECT * FROM CTE WHERE Name = '''+Name+''') '+QUOTENAME(Name)+' on t1.smallRN = '+QUOTENAME(Name)+'.rn'
FROM T
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET #col = STUFF((SELECT distinct ', ' + QUOTENAME(Name)+'.Employee as '''+ QUOTENAME(Name) +''''
FROM T
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET #col = substring(#col,1, len(#col))
set #query = '
WITH CTE AS (
SELECT *,ROW_NUMBER() OVER(PARTITION BY Name ORDER BY Name) rn
FROM T
),CTE1 AS(
SELECT MIN(rn) smallRN,MAX(rn) bigRN
FROM CTE
UNION ALL
SELECT smallRN+1,bigRN
FROM CTE1
WHERE smallRN < bigRN
)
SELECT '+#col+'
FROM CTE1 t1 ' + #tables
execute(#query)
sqlfiddle
Creatin tbale
First we will create a temp table where we will stock the data that you have and your table
create table #table1
(
[Crew Name] varchar(500) ,
Employee varchar(500)
)
INsert into #table1
values (....)
select * from #table1
Dynamic selection
then we will create a dynamic query to get the columns that we have, that way we can add as much crews as we want,
declare #DynamicPivotQuery as nvarchar(max)
declare #ColumnName as nvarchar(max)
select #ColumnName = ISNULL(#ColumnName +',','') + QUOTENAME([Crew Name])
from (select distinct [Crew Name] from #table1) as Country
set #DynamicPivotQuery = N'select ' +#ColumnName + '
from #table1
Pivot ( MAX(Employee)
FOR [Crew Name] in (' +#ColumnName+')) as Pivoted
'
exec (#DynamicPivotQuery)
this way we will get only the first row for every column
so we have to find a way to aggregate and get the other columns as well just to demonstrate i will union the Mmin also this is where i stoped my testes but you can do more then this with some testes
now the union :
declare #DynamicPivotQuery as nvarchar(max)
declare #ColumnName as nvarchar(max)
select #ColumnName = ISNULL(#ColumnName +',','') + QUOTENAME([Crew Name])
from (select distinct [Crew Name] from #table1) as Country
set #DynamicPivotQuery = N'select ' +#ColumnName + '
from #table1
Pivot ( MAX(Employee)
FOR [Crew Name] in (' +#ColumnName+')) as Pivoted
union
select ' +#ColumnName + '
from #table1
Pivot ( MIN(Employee)
FOR [Crew Name] in (' +#ColumnName+')) as Pivoted
'
exec (#DynamicPivotQuery)
here is the result :
if you follow this way i'm sure that you will find a way to union all the result
You can add this result into a temp table
then add a column which will be a reference into this temp table
then use pivot function
To know more about pivot Visit :
https://msdn.microsoft.com/en-us/azure/data-lake-analytics/u-sql/pivot-and-unpivot-u-sql
you can use also SSIS to a very handy tool and easy to use
Using dynamic PIVOT if you dont have a set Crew columns.
DECLARE #ColumnString VARCHAR(256)
DECLARE #ColumnHeadrer VARCHAR(256)
DECLARE #sql varchar(1000)
CREATE TABLE #ColumnValue
(
Value VARCHAR(500),
ColumnHeader VARCHAR(256)
)
INSERT INTO #ColumnValue (Value, ColumnHeader)
SELECT DISTINCT '[' + CrewName + ']',
'ISNULL(' + CrewName + ','''') AS ' + CrewName
FROM CrewTable
SELECT #ColumnString = COALESCE(#ColumnString + ',', '') + Value,
#ColumnHeadrer = COALESCE(#ColumnHeadrer + ',', '') + ColumnHeader
FROM #ColumnValue
SET #sql =
'
SELECT ' + #ColumnHeadrer + '
FROM
(
SELECT Employee,
CrewName,
ROW_NUMBER() OVER(PARTITION BY CrewName ORDER BY CrewName) AS rnk
FROM CrewTable
) AS P
PIVOT
(
MAX(Employee) FOR [CrewName] IN ('+#ColumnString+')
) AS pv
'
EXEC (#sql)
While Executing the Following query it showing the Invalid object name '#temp1'. can any body knows the error occurred due to which reason this is my orginal code i used to fetch code , her differnt tables are formed i need to get the sum of the each row of each table
DECLARE #t TABLE (
id int IDENTITY(1,1),
BranchName nvarchar(max)
)
DECLARE #n int = 0,
#i int = 1,
#BranchName nvarchar(max),
#sql nvarchar(max),
#columns nvarchar(max)
INSERT INTO #t
SELECT DISTINCT BranchName
FROM ALX_Branches
SELECT #n = ##ROWCOUNT
WHILE #n >= #i
BEGIN
SELECT #BranchName = BranchName
FROM #t
WHERE id = #i
SELECT #columns = (
SELECT DISTINCT ','+QUOTENAME([SubInventory])
FROM #MyTempTable
WHERE [BranchName] = #BranchName
FOR XML PATH('')
)
SELECT #sql = N'--
SELECT * into #temp1
FROM (
SELECT [BranchID],
[SubInventory],
[Product],
[Stock]
FROM #MyTempTable
WHERE [BranchName] = ''' +#BranchName +'''
) as t
PIVOT (
MAX([Stock]) FOR [SubInventory] IN ('+STUFF(#columns,1,1,'')+')
) as pvt'
EXEC sp_executesql #sql
select * from #temp1
Firstly, there is no need for creating #temp1 table before.
because you are using "Select * into" that already create table within it.
Suppose type this note as a comment, but I don't have enough reputation score.
The reason of
Invalid object name '#temp1'
is: the variable #sql is NULL because #temp1 is not created yet via "Select * into" clause.
so append selecting from #temp1 within dynamic sql as the following:
SELECT #sql = N'--
SELECT * into #temp1
FROM (
SELECT [BranchID],
[SubInventory],
[Product],
[Stock]
FROM #MyTempTable
WHERE [BranchName] = ''' +#BranchName +'''
) as t
PIVOT (
MAX([Stock]) FOR [SubInventory] IN ('+STUFF(#columns,1,1,'')+')
) as pvt
select * from #temp1 '
EXEC sp_executesql #sql
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
My code:
SELECT * INTO #t FROM CTABLE WHERE CID = #cid --get data, put into a temp table
ALTER TABLE #t
DROP COLUMN CID -- remove primary key column CID
INSERT INTO CTABLE SELECT * FROM #t -- insert record to table
DROP TABLE #t -- drop temp table
The error is:
Msg 8101,
An explicit value for the identity column in table 'CTABLE' can only
be specified when a column list is used and IDENTITY_INSERT is ON.
And I did set
SET IDENTITY_INSERT CTABLE OFF
GO
DECLARE
#cid INT,
#o INT,
#t NVARCHAR(255),
#c NVARCHAR(MAX),
#sql NVARCHAR(MAX);
SELECT
#cid = 10,
#t = N'dbo.CTABLE',
#o = OBJECT_ID(#t);
SELECT #c = STRING_AGG(QUOTENAME(name), ',')
FROM sys.columns
WHERE [object_id] = #o
AND is_identity = 0;
SET #sql = 'SELECT ' + #c + ' INTO #t
FROM ' + #t + ' WHERE CID = #cid;
INSERT ' + #t + '('+ #c + ')
SELECT ' + #c + ' FROM #t;'
PRINT #sql;
-- exec sp_executeSQL #sql,
-- N'#cid int',
-- #cid = #cid;
However it seems much easier to just build the following SQL and avoid the #temp table altogether:
SET #sql = 'INSERT ' + #t + '(' + #c + ')
SELECT ' + #c + ' FROM ' + #t + '
WHERE CID = #cid;';
PRINT #sql;
-- exec sp_executeSQL #sql,
-- N'#cid int',
-- #cid = #cid;
Try this:
SELECT * INTO #t FROM CTABLE WHERE CID = #cid
ALTER TABLE #t
DROP COLUMN CID
INSERT CTABLE --Notice that INTO is removed here.
SELECT top(1) * FROM #t
DROP TABLE #t
Test Script(Tested in SQL 2005):
CREATE TABLE #TestIDNT
(
ID INT IDENTITY(1,1) PRIMARY KEY,
TITLE VARCHAR(20)
)
INSERT #TestIDNT
SELECT 'Cybenate'
Try specifying the columns:
INSERT INTO CTABLE
(col2, col3, col4)
SELECT col2, col3, col4
FROM #t
Seems like it might be thinking you are trying to insert into the PK field since you are not explicitly defining the columns to insert into. If Identity insert is off and you specify the non-pk columns then you shouldn't get that error.
Here's an example to dynamically build a list of columns - excluding the primary key columns - and execute the INSERT
declare #tablename nvarchar(100), #column nvarchar(100), #cid int, #sql nvarchar(max)
set #tablename = N'ctable'
set #cid = 1
set #sql = N''
declare example cursor for
select column_name
from information_schema.columns
where table_name = #tablename
and column_name not in (
select column_name
from information_schema.key_column_usage
where constraint_name in (select constraint_name from information_schema.table_constraints)
and table_name = #tablename
)
open example
fetch next from example into #column
while ##fetch_status = 0
begin
set #sql = #sql + N'[' + #column + N'],'
fetch next from example into #column
end
set #sql = substring(#sql, 1, len(#sql)-1)
close example
deallocate example
set #sql = N'insert into ' + #tablename + '(' + #sql + N') select top(1) ' + #sql + ' from #t'
--select #sql
exec sp_executesql #sql
If using SQL Server Management Studio and your problems you have too many fields to type them all out except the identity column, then right click on the table and click "Script table as" / "Select To" / "New Query Window".
This will provide a list of fields that you can copy & paste into your own query and then just remove the identity column.
Try invoking the INSERT statement with EXEC:
SELECT * INTO #t FROM CTABLE WHERE CID = #cid
ALTER TABLE #t
DROP COLUMN CID
EXEC('INSERT INTO CTABLE SELECT top(1) * FROM #t')
DROP TABLE #t
You can't do this:
INSERT INTO CTABLE SELECT top(1) * FROM #t
Because the column listings aren't the same. You've dropped the PK column from #t, so you have 1 less column in #t than in CTABLE. This is the equivalent of the following:
INSERT INTO CTABLE(pk, col1, col2, col3, ...)
select top(1) col1, col2, col3, ...
from #t
This wouldn't work for obvious reasons. Similarly, you aren't going to be able to specify the * wildcard to do the insert if you're not inserting all of the columns. The only way to do the insert without including the PK is to specify every column. You can generate a list of columns through dynamic sql, but you'll have to specify them one way or another.