I was trying to do a dynamic pivot on two columns to rearrange some data. Her is my original table:
Initial table
I used the flowing code to pivot the BRAND based on CountryID and GenericArticle but I get following result (as you can see the table doesn't seem to be GROUPed BY)
Result after pivot
Here is my Pivot Code:
DECLARE #DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE #ColumnName AS NVARCHAR(MAX)
SELECT #ColumnName= ISNULL(#ColumnName + ',','')
+ QUOTENAME(Brand)
FROM (SELECT DISTINCT [Brand]
FROM #tempProgCov) AS Country
SET #DynamicPivotQuery =
N'SELECT [CountryID], [GenericArticle], ' + #ColumnName + '
INTO ##ProgCovPivot
FROM #tempProgCov as Src
PIVOT
(
SUM([Coverage])
FOR [Brand] IN (' + #ColumnName + ')
) as Pvt'
EXEC sp_executesql #DynamicPivotQuery
Any help highly appreciated, thx!
PS, was expecting something like this:
Desired result
Never-mind, I solved it eventually, was just under my eye. Problem was in source table select:
DECLARE #DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE #ColumnName AS NVARCHAR(MAX)
SELECT #ColumnName= ISNULL(#ColumnName + ',','')
+ QUOTENAME(Brand)
FROM (SELECT DISTINCT [Brand]
FROM #tempProgCov) AS Country
SET #DynamicPivotQuery =
N'SELECT [CountryID], [GenericArticle], ' + #ColumnName + '
INTO ##ProgCovPivot
FROM (SELECT CountryID,
Brand,
GenericArticle,
Coverage
FROM #tempProgCov) as Src
PIVOT
(
SUM([Coverage])
FOR [Brand] IN (' + #ColumnName + ')
) as Pvt'
EXEC sp_executesql #DynamicPivotQuery
Related
I create a Script sql-server that returns two html code from two different views that I created. The problem is that, when I'm running the .sql file (scrip) in sqlcmd, the html result in the file output is incomplete (obs. If I execute in management studio, the result in html is complete).
I have no idea how to proceed. I think in Oracle set long is used, but I don't know in Microsoft SQL Server.
--CODE IN SQLCMD
--SQLCMD -S LOCALHOST\SQLEXPRESS -i C:\checklist_sql\check_sql\checklist.sql -o C:\checklist_sql\lib\resultado.html
SET NOCOUNT ON;
---------ROCEDUR TO HTML----
GO
create PROCEDURE [dbo].[SqlTableToHtml] (
#TABLENAME NVARCHAR(500),
#OUTPUT NVARCHAR(MAX) OUTPUT,
#TBL_STYLE NVARCHAR(1024) = '',
#TD_STYLE NVARCHAR(1024) = '',
#HDR_STYLE NVARCHAR(1024) = '')
AS
-- Description
-- Stored Procedure to take an arbitraty temporary table and return
-- the equivalent HTML string .
-- #exec_str stores the dynamic SQL Query
-- #ParmDefinition stores the parameter definition for the dynamic SQL
DECLARE #exec_str NVARCHAR(MAX)
DECLARE #ParmDefinition NVARCHAR(500)
--We need to use Dynamic SQL at this point so we can expand the input table name parameter
SET #exec_str= N'
DECLARE #exec_str NVARCHAR(MAX)
DECLARE #ParmDefinition NVARCHAR(500)
--Make a copy of the original table adding an indexing columnWe need to add an index column to the table to facilitate sorting so we can maintain the
--original table order as we iterate through adding HTML tags to the table fields.
--New column called CustColHTML_ID (unlikely to be used by someone else!)
--
select CustColHTML_ID=0,* INTO #CustomTable2HTML FROM ' + #TABLENAME + '
--Now alter the table to add the auto-incrementing index. This will facilitate row finding
DECLARE #COUNTER INT
SET #COUNTER=0
UPDATE #CustomTable2HTML SET #COUNTER = CustColHTML_ID=#COUNTER+1
-- #HTMLROWS will store all the rows in HTML format
-- #ROW will store each HTML row as fields on each row are iterated through
-- using dymamic SQL and a cursor
-- #FIELDS will store the header row for the HTML Table
DECLARE #HTMLROWS NVARCHAR(MAX) DECLARE #FIELDS NVARCHAR(MAX)
SET #HTMLROWS='''' DECLARE #ROW NVARCHAR(MAX)
-- Create the first HTML row for the table (the table header). Ignore our indexing column!
SET #FIELDS=''<tr>''
SELECT #FIELDS=COALESCE(#FIELDS, '' '','''')+''<th ' + #HDR_STYLE + '>'' + name + ''</th>''
FROM tempdb.sys.Columns
WHERE object_id=object_id(''tempdb..#CustomTable2HTML'')
AND name not like ''CustColHTML_ID''
SET #FIELDS=#FIELDS + ''</tr>''
-- #ColumnName stores the column name as found by the table cursor
-- #maxrows is a count of the rows in the table, and #rownum is for marking the
-- ''current'' row whilst processing
DECLARE #ColumnName NVARCHAR(500)
DECLARE #maxrows INT
DECLARE #rownum INT
--Find row count of our temporary table
SELECT #maxrows=count(*) FROM #CustomTable2HTML
--Create a cursor which will look through all the column names specified in the temporary table
--but exclude the index column we added (CustColHTML_ID)
DECLARE col CURSOR FOR
SELECT name FROM tempdb.sys.Columns
WHERE object_id=object_id(''tempdb..#CustomTable2HTML'')
AND name not like ''CustColHTML_ID''
ORDER BY column_id ASC
--For each row, generate dymanic SQL which requests the each column name in turn by
--iterating through a cursor
SET #rowNum=0
SET #ParmDefinition=N''#ROWOUT NVARCHAR(MAX) OUTPUT,#rowNum_IN INT''
While #rowNum < #maxrows
BEGIN
SET #HTMLROWS=#HTMLROWS + ''<tr>''
SET #rowNum=#rowNum +1
OPEN col
FETCH NEXT FROM col INTO #ColumnName
WHILE ##FETCH_STATUS=0
BEGIN
--Get nth row from table
SET #exec_str=''SELECT #ROWOUT=(select COALESCE(['' + #ColumnName + ''], '''''''') AS ['' + #ColumnName + ''] from #CustomTable2HTML where CustColHTML_ID=#rowNum_IN)''
EXEC sp_executesql
#exec_str,
#ParmDefinition,
#ROWOUT=#ROW OUTPUT,
#rowNum_IN=#rownum
SET #HTMLROWS =#HTMLROWS + ''<td ' + #TD_STYLE + '>'' + #ROW + ''</td>''
FETCH NEXT FROM col INTO #ColumnName
END
CLOSE col
SET #HTMLROWS=#HTMLROWS + ''</tr>''
END
SET #OUTPUT=''''
IF #maxrows>0
SET #OUTPUT= ''<table ' + #TBL_STYLE + '>'' + #FIELDS + #HTMLROWS + ''</table>''
DEALLOCATE col
'
DECLARE #ParamDefinition nvarchar(max)
SET #ParamDefinition=N'#OUTPUT NVARCHAR(MAX) OUTPUT'
--Execute Dynamic SQL. HTML table is stored in #OUTPUT which is passed back up (as it's
--a parameter to this SP)
EXEC sp_executesql #exec_str,
#ParamDefinition,
#OUTPUT=#OUTPUT OUTPUT
RETURN 1;
---- VIEW VERSION SQL--
GO
create view versao_sql as
SELECT Convert(nvarchar(30),SERVERPROPERTY('MachineName')) AS [NOME DA MAQUINA] ,
Convert(nvarchar(30),SERVERPROPERTY('InstanceName')) AS [INSTANCIA] ,
Convert(nvarchar(30),SERVERPROPERTY('ProductVersion')) AS [PRODUCT VERSION],
Convert(nvarchar(30),SERVERPROPERTY('ProductLevel')) AS [PRODUCT LEVEL] ,
Convert(nvarchar(30),SERVERPROPERTY('Edition')) AS [EDIÇÃO] ,
( CASE SERVERPROPERTY('EngineEdition')
WHEN 1 THEN 'Personal or Desktop'
WHEN 2 THEN 'Standard'
WHEN 3 THEN 'Enterprise'
else ''
END ) AS [ENGINE TYPE] ,
Convert(nvarchar(30),SERVERPROPERTY('LicenseType')) AS [TIPO DE LICENÇA] ,
convert(nvarchar(30), SERVERPROPERTY('NumLicenses')) AS [LICENÇAS] ,
( CASE SERVERPROPERTY('IsIntegratedSecurityOnly')
WHEN 0 THEN 'Mista'
WHEN 1 THEN 'Integrada'
else ''
END ) AS [SOMENTE SEGURANÇA INTEGRADA] ,
convert(nvarchar(30),SERVERPROPERTY('Collation')) AS [COLLATION] ,
( CASE SERVERPROPERTY('IsClustered')
WHEN 0 THEN 'Nao'
WHEN 1 THEN 'Sim'
END ) AS [CLUSTER];
------INFO INSTANCE--
GO
create view info_instancia as
select 'VERSAO DO CHECK LIST' as DESCRICAO,'2.2.6' as VALOR
union all
select 'NOME DO SERVIDOR' as DESCRICAO, CAST(##SERVERNAME as nvarchar) as VALOR
union all
select 'IP DO SERVIDOR' as DESCRICAO, CAST(CONNECTIONPROPERTY('local_net_address') as nvarchar) as VALOR
union all
select 'NOME DA INSTANCIA' as DESCRICAO, CAST(SERVERPROPERTY('InstanceName') as nvarchar) as VALOR
union all
select 'NLS_CHARACTERSET' as DESCRICAO, CAST(SERVERPROPERTY('Collation') as nvarchar) as VALOR
union all
select 'VERSAO SQL SERVER' as DESCRICAO, CAST(##VERSION as nvarchar) as VALOR
union all
select 'DATA DE HOJE' as DESCRICAO, CAST(GETDATE() as nvarchar) as VALOR;
-- RUNNING PROCEDURE FOR EACH VIEW
GO
--SQL VERSION
declare #html nvarchar(max)
exec SqlTableToHtml 'versao_sql', #html output, 'style="table:"border=1 width=65%"', '', 'style="scope=col"'
select #html;
GO
--INSTANCE SQL
declare #html nvarchar(max)
exec SqlTableToHtml 'info_instancia', #html output, 'style="table:"border=1 width=65%"', '', 'style="scope=col"'
select #html;
----DROPINGS----
GO
drop view versao_sql;
GO
drop view info_instancia;
GO
DROP PROCEDURE SqlTableToHtml;
So i have this:
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_Transactions WHERE lAccountNO LIKE '6%' AND Period LIKE '2017%') AS Periods
SET #DynamicPivotQuery =
N'SELECT lAccountNo, ' + #ColumnName + '
FROM (SELECT
lAccountNo, period, SUM(Amount) As Total
FROM atbv_Accounting_Transactions
WHERE lAccountNO LIKE ''6%'' AND Period LIKE ''2017%''
GROUP BY lAccountNo, period
) AS T
PIVOT(SUM(TOTAL)
FOR period IN (' + #ColumnName + ')) AS PVTTable'
--Execute the Dynamic Pivot Query
EXEC sp_executesql #DynamicPivotQuery
It returns me this:
How do i remove decimal places within select itself. I cannot edit column in the table and reduce the decimal places.So i need to edit this query to return values without decimals.
Thanks!
Should just change SUM(Amount) to cast(SUM(Amount) as int) or perhaps floor(SUM(Amount)) and it will do the trick.
I need some help on this. I use this code to export SQL queries to html tables (got code from Convert a SQL query result table to an HTML table for email)
-- Description: Turns a query into a formatted HTML table. Useful for emails.
-- Any ORDER BY clause needs to be passed in the separate ORDER BY parameter.
-- =============================================
CREATE PROC [dbo].[spQueryToHtmlTable]
(
#query nvarchar(MAX), --A query to turn into HTML format. It should not include an ORDER BY clause.
#orderBy nvarchar(MAX) = NULL, --An optional ORDER BY clause. It should contain the words 'ORDER BY'.
#html nvarchar(MAX) = NULL OUTPUT --The HTML output of the procedure.
)
AS
BEGIN
SET NOCOUNT ON;
IF #orderBy IS NULL BEGIN
SET #orderBy = ''
END
SET #orderBy = REPLACE(#orderBy, '''', '''''');
DECLARE #realQuery nvarchar(MAX) = '
DECLARE #headerRow nvarchar(MAX);
DECLARE #cols nvarchar(MAX);
SELECT * INTO #dynSql FROM (' + #query + ') sub;
SELECT #cols = COALESCE(#cols + '', '''''''', '', '''') + ''['' + name + ''] AS ''''td''''''
FROM tempdb.sys.columns
WHERE object_id = object_id(''tempdb..#dynSql'')
ORDER BY column_id;
SET #cols = ''SET #html = CAST(( SELECT '' + #cols + '' FROM #dynSql ' + #orderBy + ' FOR XML PATH(''''tr''''), ELEMENTS XSINIL) AS nvarchar(max))''
EXEC sys.sp_executesql #cols, N''#html nvarchar(MAX) OUTPUT'', #html=#html OUTPUT
SELECT #headerRow = COALESCE(#headerRow + '''', '''') + ''<th>'' + name + ''</th>''
FROM tempdb.sys.columns
WHERE object_id = object_id(''tempdb..#dynSql'')
ORDER BY column_id;
SET #headerRow = ''<tr>'' + #headerRow + ''</tr>'';
SET #html = ''<table border="1">'' + #headerRow + #html + ''</table>'';
';
EXEC sys.sp_executesql #realQuery, N'#html nvarchar(MAX) OUTPUT', #html=#html OUTPUT
END
GO
The code works perfect, but has one problem formatting float values.
For example:
SELECT Name, Weight FROM Products
The query returns something like this when executed from Management Studio:
Name1 | 1073,822
Name2 | 179,554
When I use the stored procedure to export this to html table, then I get the results like this:
Name1 | 1.073822000000000e+003
Name2 | 1.795540000000000e+002
Don't know exactly how to change the stored procedure to adapt it in order to avoid this wrong formatting on float values.
Any help on this would be appreciated.
you are using cast to show the values in the html-table:
SET #cols = ''SET #html = CAST(( SELECT '' + #cols + '' FROM #dynSql ' + #orderBy + ' FOR XML PATH(''''tr''''), ELEMENTS XSINIL) AS nvarchar(max))''
MS-Help tells you more, but basically this is the automatic behavior of cast with a float value.
You should try to already convert your float-fields to the desired format in the query you pass, using the STR() function, see str function description
Many thanks for your reply
EDIT: If I take out the casting to varchar(max), the result seems to be the same.
But I've just tried to do something like this:
SELECT Name, CAST(Weight AS varchar(max)) FROM Products
And I still can see the right formatted values:
Name1 | 1073.82
Name2 | 179.554
Otherwise, I use this SP to be called from many sites and processes. Is not possible to check every case and try to cast the float fields.
I need a solution to be implemented at the SP level.
I've tried to use the STR() function, so changed the line:
SET #cols = ''SET #html = CAST(( SELECT '' + #cols + '' FROM #dynSql ' + #orderBy + ' FOR XML PATH(''''tr''''), ELEMENTS XSINIL) AS nvarchar(max))''
To
SET #cols = ''SET #html = STR(( SELECT '' + #cols + '' FROM #dynSql ' + #orderBy + ' FOR XML PATH(''''tr''''), ELEMENTS XSINIL))''
But then I'm getting the error: Error converting data type nvarchar to float.
Not sure if this is what you mentioned.
Would be a way to check the field type in the SP, and use a different casting for the float cases?
How could I do it?
Regards,
I'm trying to use This question to perform a dynamic pivot, but I want to use a CTE to get the initial data.
My query looks like this:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
WITH dataSet (coDate, TransactionDate, TotalBalance, TransDate, collected)
AS
( *SELECT STATEMENT )
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(c.category)
FROM dataSet c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT coDate, ' + #cols + ' from
(
select coDate
, TotalBalance
, collected
, TransDate
from dataSet
) x
pivot
(
SUM(collected)
for category in (' + #cols + ')
) p '
execute(#query)
And the error SQL gives me is Incorrect syntax near the keyword 'SET'. I did try adding a semicolon and go as well as a comma before the SET statement, but this the first time I've used PIVOT so I'm not sure how CTE interacts with it.
I am trying to load the trace from physical table which is store table name and trace path.
I would like to make NewTableName and Tracepath as dynamic which will take from variables.
My Input :
select * into NewTableName
FROM fn_trace_gettable('Tracepath\tracename.trc' ,DEFAULT)
Output: Required Dynamic SQL.
Do you mean something like this?
DECLARE #TableName NVARCHAR(MAX) = 'NewTableName';
DECLARE #Tracepath NVARCHAR(MAX) = 'Tracepath\tracename.trc';
DECLARE #sql NVARCHAR(MAX)
SET #sql = 'select * into ' + #TableName + '
FROM fn_trace_gettable(''' + #Tracepath + ''' ,DEFAULT)';
EXEC (#sql)