I want to run a query that shows me all columns from all tables in a database with the datatype varchar and a maximum length of 8000 characters.
This is my code so far.
DECLARE #tabs VARCHAR(MAX);
SET #tabs =
(
SELECT STUFF(( SELECT DISTINCT ',' + [TABLE_NAME]
FROM [DB-Test].INFORMATION_SCHEMA.COLUMNS
WHERE DATA_TYPE = 'VARCHAR' AND
CHARACTER_MAXIMUM_LENGTH = 8000
FOR XML PATH('')), 1, 1, '')
);
DECLARE #cols VARCHAR(MAX)
SET #cols =
(
SELECT STUFF(( SELECT DISTINCT ',' + [TABLE_NAME] + '.' + [COLUMN_NAME]
FROM [DB-Test].INFORMATION_SCHEMA.COLUMNS
WHERE DATA_TYPE = 'VARCHAR' AND
CHARACTER_MAXIMUM_LENGTH = 8000
FOR XML PATH('')), 1, 1, '')
);
DECLARE #query VARCHAR(MAX) = 'SELECT ' + #cols + ' FROM ' + #tabs
EXEC sp_sqlexec #query
When I run the query I get all the column names, but not the values in the columns. It's empty. No 'NULL'-values. As if #cols is interpreted as simple string maybe.
Why?
(When I read out #cols and #tabs they are correct.)
I guess there is one table available in your database which have column with VARCHAR datatype and 8000 length but that table don't have any records. Try by including only those column and table which have at least one record available.
You can try below. Check it and let me know if it works.
DECLARE #tabs VARCHAR(MAX) = ''
; WITH CTE AS
(
SELECT DISTINCT TA.NAME TABLENAME
, SUM(PA.ROWS) OVER (PARTITION BY TA.NAME ) NOOFROW
FROM SYS.TABLES TA
INNER JOIN SYS.PARTITIONS PA ON PA.OBJECT_ID = TA.OBJECT_ID
INNER JOIN SYS.SCHEMAS SC ON TA.SCHEMA_ID = SC.SCHEMA_ID
WHERE TA.IS_MS_SHIPPED = 0 AND PA.INDEX_ID IN (1,0)
), TABLENAME AS
(
SELECT ITBL.[TABLE_NAME]
FROM INFORMATION_SCHEMA.COLUMNS ITBL
WHERE ITBL.DATA_TYPE = 'VARCHAR' AND
ITBL.CHARACTER_MAXIMUM_LENGTH = 8000
AND EXISTS(SELECT 1 FROM CTE WHERE CTE.TABLENAME = ITBL.TABLE_NAME AND CTE.NOOFROW > 0) -- To check no of record available in table
)
SELECT #tabs = #tabs+ISNULL(','+TABLE_NAME, '')
FROM TABLENAME
DECLARE #cols VARCHAR(MAX) = '';
; WITH CTE AS
(
SELECT DISTINCT TA.NAME TABLENAME
, SUM(PA.ROWS) OVER (PARTITION BY TA.NAME ) NOOFROW
FROM SYS.TABLES TA
INNER JOIN SYS.PARTITIONS PA ON PA.OBJECT_ID = TA.OBJECT_ID
INNER JOIN SYS.SCHEMAS SC ON TA.SCHEMA_ID = SC.SCHEMA_ID
WHERE TA.IS_MS_SHIPPED = 0 AND PA.INDEX_ID IN (1,0)
), TABLENAME AS
(
SELECT ITBL.[TABLE_NAME], ITBL.[COLUMN_NAME]
FROM INFORMATION_SCHEMA.COLUMNS ITBL
WHERE ITBL.DATA_TYPE = 'VARCHAR' AND
ITBL.CHARACTER_MAXIMUM_LENGTH = 8000
AND EXISTS(SELECT 1 FROM CTE WHERE CTE.TABLENAME = ITBL.TABLE_NAME AND CTE.NOOFROW > 0) -- To check no of record available in table
)
SELECT #cols = #cols+ISNULL(','+[TABLE_NAME]+'.'+[COLUMN_NAME], '')
FROM TABLENAME
IF LEN(#cols) > 0 AND LEN(#tabs) > 0
BEGIN
DECLARE #query VARCHAR(MAX) = 'SELECT ' + STUFF(#cols,1,1,'') + ' FROM ' + STUFF(#tabs,1,1, '')
EXEC sp_sqlexec #query
END
ELSE
BEGIN
PRINT 'No Column available with data where it''s datatype is VARCHAR and length is 8000'
END
I have a Emplyee table as Follow,
https://i.stack.imgur.com/WjtM6.png
In every Updation(any column Delete,Update) ineed save that details to another table for security purpose.That tbale structure as following.
https://i.stack.imgur.com/Yv1YD.png
I can write a Code in my programe to do this job, but Can i write a trigger to Automatically saved old data to employee updation table using triger?
in a MySql that function availble, I dont Konw about MS SQL.
thank you!
i would suggest to create audit table similar to original table
IF NOT EXISTS
(SELECT * FROM sysobjects WHERE id = OBJECT_ID(N'[dbo].[Audit]')
AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
CREATE TABLE Audit
(Type CHAR(1),
TableName VARCHAR(128),
PK VARCHAR(1000),
FieldName VARCHAR(128),
OldValue VARCHAR(1000),
NewValue VARCHAR(1000),
UpdateDate datetime,
UserName VARCHAR(128))
GO
Then work on the trigger as below, which can track, INSERT, UPDATE and DELETE operations.
CREATE TRIGGER TR_GUESTS_AUDIT ON dbo.IBIS_UnitSchedule FOR UPDATE
AS
DECLARE #bit INT ,
#field INT ,
#maxfield INT ,
#char INT ,
#fieldname VARCHAR(128) ,
#TableName VARCHAR(128) ,
#PKCols VARCHAR(1000) ,
#sql VARCHAR(2000),
#UpdateDate VARCHAR(21) ,
#UserName VARCHAR(128) ,
#Type CHAR(1) ,
#PKSelect VARCHAR(1000)
SELECT #TableName = 'dbo.IBIS_UnitSchedule'
-- date and user
SELECT #UserName = SYSTEM_USER ,
#UpdateDate = CONVERT (NVARCHAR(30),GETDATE(),126)
-- Action
IF EXISTS (SELECT * FROM inserted)
IF EXISTS (SELECT * FROM deleted)
SELECT #Type = 'U'
ELSE
SELECT #Type = 'I'
ELSE
SELECT #Type = 'D'
-- get list of columns
SELECT * INTO #ins FROM inserted
SELECT * INTO #del FROM deleted
-- Get primary key columns for full outer join
SELECT #PKCols = COALESCE(#PKCols + ' and', ' on')
+ ' i.' + c.COLUMN_NAME + ' = d.' + c.COLUMN_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk ,
INFORMATION_SCHEMA.KEY_COLUMN_USAGE c
WHERE pk.TABLE_NAME = #TableName
AND CONSTRAINT_TYPE = 'PRIMARY KEY'
AND c.TABLE_NAME = pk.TABLE_NAME
AND c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME
-- Get primary key select for insert
SELECT #PKSelect = COALESCE(#PKSelect+'+','')
+ '''<' + COLUMN_NAME
+ '=''+convert(varchar(100),
coalesce(i.' + COLUMN_NAME +',d.' + COLUMN_NAME + '))+''>'''
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk ,
INFORMATION_SCHEMA.KEY_COLUMN_USAGE c
WHERE pk.TABLE_NAME = #TableName
AND CONSTRAINT_TYPE = 'PRIMARY KEY'
AND c.TABLE_NAME = pk.TABLE_NAME
AND c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME
IF #PKCols IS NULL
BEGIN
RAISERROR('no PK on table %s', 16, -1, #TableName)
RETURN
END
SELECT #field = 0,
#maxfield = MAX(ORDINAL_POSITION)
FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = #TableName
WHILE #field < #maxfield
BEGIN
SELECT #field = MIN(ORDINAL_POSITION)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = #TableName
AND ORDINAL_POSITION > #field
SELECT #bit = (#field - 1 )% 8 + 1
SELECT #bit = POWER(2,#bit - 1)
SELECT #char = ((#field - 1) / 8) + 1
IF SUBSTRING(COLUMNS_UPDATED(),#char, 1) & #bit > 0
OR #Type IN ('I','D')
BEGIN
SELECT #fieldname = COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = #TableName
AND ORDINAL_POSITION = #field
SELECT #sql = '
insert Audit ( Type,
TableName,
PK,
FieldName,
OldValue,
NewValue,
UpdateDate,
UserName)
select ''' + #Type + ''','''
+ #TableName + ''',' + #PKSelect
+ ',''' + #fieldname + ''''
+ ',convert(varchar(1000),d.' + #fieldname + ')'
+ ',convert(varchar(1000),i.' + #fieldname + ')'
+ ',''' + #UpdateDate + ''''
+ ',''' + #UserName + ''''
+ ' from #ins i full outer join #del d'
+ #PKCols
+ ' where i.' + #fieldname + ' <> d.' + #fieldname
+ ' or (i.' + #fieldname + ' is null and d.'
+ #fieldname
+ ' is not null)'
+ ' or (i.' + #fieldname + ' is not null and d.'
+ #fieldname
+ ' is null)'
EXEC (#sql)
END
END
GO
I'm looking for an efficient way to convert rows to columns in SQL server, I heard that PIVOT is not very fast, and I need to deal with lot of records.
This is my example:
-------------------------------
| Id | Value | ColumnName |
-------------------------------
| 1 | John | FirstName |
| 2 | 2.4 | Amount |
| 3 | ZH1E4A | PostalCode |
| 4 | Fork | LastName |
| 5 | 857685 | AccountNumber |
-------------------------------
This is my result:
---------------------------------------------------------------------
| FirstName |Amount| PostalCode | LastName | AccountNumber |
---------------------------------------------------------------------
| John | 2.4 | ZH1E4A | Fork | 857685 |
---------------------------------------------------------------------
How can I build the result?
There are several ways that you can transform data from multiple rows into columns.
Using PIVOT
In SQL Server you can use the PIVOT function to transform the data from rows to columns:
select Firstname, Amount, PostalCode, LastName, AccountNumber
from
(
select value, columnname
from yourtable
) d
pivot
(
max(value)
for columnname in (Firstname, Amount, PostalCode, LastName, AccountNumber)
) piv;
See Demo.
Pivot with unknown number of columnnames
If you have an unknown number of columnnames that you want to transpose, then you can use dynamic SQL:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT ',' + QUOTENAME(ColumnName)
from yourtable
group by ColumnName, id
order by id
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = N'SELECT ' + #cols + N' from
(
select value, ColumnName
from yourtable
) x
pivot
(
max(value)
for ColumnName in (' + #cols + N')
) p '
exec sp_executesql #query;
See Demo.
Using an aggregate function
If you do not want to use the PIVOT function, then you can use an aggregate function with a CASE expression:
select
max(case when columnname = 'FirstName' then value end) Firstname,
max(case when columnname = 'Amount' then value end) Amount,
max(case when columnname = 'PostalCode' then value end) PostalCode,
max(case when columnname = 'LastName' then value end) LastName,
max(case when columnname = 'AccountNumber' then value end) AccountNumber
from yourtable
See Demo.
Using multiple joins
This could also be completed using multiple joins, but you will need some column to associate each of the rows which you do not have in your sample data. But the basic syntax would be:
select fn.value as FirstName,
a.value as Amount,
pc.value as PostalCode,
ln.value as LastName,
an.value as AccountNumber
from yourtable fn
left join yourtable a
on fn.somecol = a.somecol
and a.columnname = 'Amount'
left join yourtable pc
on fn.somecol = pc.somecol
and pc.columnname = 'PostalCode'
left join yourtable ln
on fn.somecol = ln.somecol
and ln.columnname = 'LastName'
left join yourtable an
on fn.somecol = an.somecol
and an.columnname = 'AccountNumber'
where fn.columnname = 'Firstname'
This is rather a method than just a single script but gives you much more flexibility.
First of all There are 3 objects:
User defined TABLE type [ColumnActionList] -> holds data as
parameter
SP [proc_PivotPrepare] -> prepares our data
SP [proc_PivotExecute] -> execute the script
CREATE TYPE [dbo].[ColumnActionList] AS TABLE
(
[ID] [smallint] NOT NULL,
[ColumnName] nvarchar NOT NULL,
[Action] nchar NOT NULL
);
GO
CREATE PROCEDURE [dbo].[proc_PivotPrepare]
(
#DB_Name nvarchar(128),
#TableName nvarchar(128)
)
AS
SELECT #DB_Name = ISNULL(#DB_Name,db_name())
DECLARE #SQL_Code nvarchar(max)
DECLARE #MyTab TABLE (ID smallint identity(1,1), [Column_Name] nvarchar(128), [Type] nchar(1), [Set Action SQL] nvarchar(max));
SELECT #SQL_Code = 'SELECT [<| SQL_Code |>] = '' '' '
+ 'UNION ALL '
+ 'SELECT ''----------------------------------------------------------------------------------------------------'' '
+ 'UNION ALL '
+ 'SELECT ''-----| Declare user defined type [ID] / [ColumnName] / [PivotAction] '' '
+ 'UNION ALL '
+ 'SELECT ''----------------------------------------------------------------------------------------------------'' '
+ 'UNION ALL '
+ 'SELECT ''DECLARE #ColumnListWithActions ColumnActionList;'''
+ 'UNION ALL '
+ 'SELECT ''----------------------------------------------------------------------------------------------------'' '
+ 'UNION ALL '
+ 'SELECT ''-----| Set [PivotAction] (''''S'''' as default) to select dimentions and values '' '
+ 'UNION ALL '
+ 'SELECT ''-----|'''
+ 'UNION ALL '
+ 'SELECT ''-----| ''''S'''' = Stable column || ''''D'''' = Dimention column || ''''V'''' = Value column '' '
+ 'UNION ALL '
+ 'SELECT ''----------------------------------------------------------------------------------------------------'' '
+ 'UNION ALL '
+ 'SELECT ''INSERT INTO #ColumnListWithActions VALUES ('' + CAST( ROW_NUMBER() OVER (ORDER BY [NAME]) as nvarchar(10)) + '', '' + '''''''' + [NAME] + ''''''''+ '', ''''S'''');'''
+ 'FROM [' + #DB_Name + '].sys.columns '
+ 'WHERE object_id = object_id(''[' + #DB_Name + ']..[' + #TableName + ']'') '
+ 'UNION ALL '
+ 'SELECT ''----------------------------------------------------------------------------------------------------'' '
+ 'UNION ALL '
+ 'SELECT ''-----| Execute sp_PivotExecute with parameters: columns and dimentions and main table name'' '
+ 'UNION ALL '
+ 'SELECT ''----------------------------------------------------------------------------------------------------'' '
+ 'UNION ALL '
+ 'SELECT ''EXEC [dbo].[sp_PivotExecute] #ColumnListWithActions, ' + '''''' + #TableName + '''''' + ';'''
+ 'UNION ALL '
+ 'SELECT ''----------------------------------------------------------------------------------------------------'' '
EXECUTE SP_EXECUTESQL #SQL_Code;
GO
CREATE PROCEDURE [dbo].[sp_PivotExecute]
(
#ColumnListWithActions ColumnActionList ReadOnly
,#TableName nvarchar(128)
)
AS
--#######################################################################################################################
--###| Step 1 - Select our user-defined-table-variable into temp table
--#######################################################################################################################
IF OBJECT_ID('tempdb.dbo.#ColumnListWithActions', 'U') IS NOT NULL DROP TABLE #ColumnListWithActions;
SELECT * INTO #ColumnListWithActions FROM #ColumnListWithActions;
--#######################################################################################################################
--###| Step 2 - Preparing lists of column groups as strings:
--#######################################################################################################################
DECLARE #ColumnName nvarchar(128)
DECLARE #Destiny nchar(1)
DECLARE #ListOfColumns_Stable nvarchar(max)
DECLARE #ListOfColumns_Dimension nvarchar(max)
DECLARE #ListOfColumns_Variable nvarchar(max)
--############################
--###| Cursor for List of Stable Columns
--############################
DECLARE ColumnListStringCreator_S CURSOR FOR
SELECT [ColumnName]
FROM #ColumnListWithActions
WHERE [Action] = 'S'
OPEN ColumnListStringCreator_S;
FETCH NEXT FROM ColumnListStringCreator_S
INTO #ColumnName
WHILE ##FETCH_STATUS = 0
BEGIN
SELECT #ListOfColumns_Stable = ISNULL(#ListOfColumns_Stable, '') + ' [' + #ColumnName + '] ,';
FETCH NEXT FROM ColumnListStringCreator_S INTO #ColumnName
END
CLOSE ColumnListStringCreator_S;
DEALLOCATE ColumnListStringCreator_S;
--############################
--###| Cursor for List of Dimension Columns
--############################
DECLARE ColumnListStringCreator_D CURSOR FOR
SELECT [ColumnName]
FROM #ColumnListWithActions
WHERE [Action] = 'D'
OPEN ColumnListStringCreator_D;
FETCH NEXT FROM ColumnListStringCreator_D
INTO #ColumnName
WHILE ##FETCH_STATUS = 0
BEGIN
SELECT #ListOfColumns_Dimension = ISNULL(#ListOfColumns_Dimension, '') + ' [' + #ColumnName + '] ,';
FETCH NEXT FROM ColumnListStringCreator_D INTO #ColumnName
END
CLOSE ColumnListStringCreator_D;
DEALLOCATE ColumnListStringCreator_D;
--############################
--###| Cursor for List of Variable Columns
--############################
DECLARE ColumnListStringCreator_V CURSOR FOR
SELECT [ColumnName]
FROM #ColumnListWithActions
WHERE [Action] = 'V'
OPEN ColumnListStringCreator_V;
FETCH NEXT FROM ColumnListStringCreator_V
INTO #ColumnName
WHILE ##FETCH_STATUS = 0
BEGIN
SELECT #ListOfColumns_Variable = ISNULL(#ListOfColumns_Variable, '') + ' [' + #ColumnName + '] ,';
FETCH NEXT FROM ColumnListStringCreator_V INTO #ColumnName
END
CLOSE ColumnListStringCreator_V;
DEALLOCATE ColumnListStringCreator_V;
SELECT #ListOfColumns_Variable = LEFT(#ListOfColumns_Variable, LEN(#ListOfColumns_Variable) - 1);
SELECT #ListOfColumns_Dimension = LEFT(#ListOfColumns_Dimension, LEN(#ListOfColumns_Dimension) - 1);
SELECT #ListOfColumns_Stable = LEFT(#ListOfColumns_Stable, LEN(#ListOfColumns_Stable) - 1);
--#######################################################################################################################
--###| Step 3 - Preparing table with all possible connections between Dimension columns excluding NULLs
--#######################################################################################################################
DECLARE #DIM_TAB TABLE ([DIM_ID] smallint, [ColumnName] nvarchar(128))
INSERT INTO #DIM_TAB
SELECT [DIM_ID] = ROW_NUMBER() OVER(ORDER BY [ColumnName]), [ColumnName] FROM #ColumnListWithActions WHERE [Action] = 'D';
DECLARE #DIM_ID smallint;
SELECT #DIM_ID = 1;
DECLARE #SQL_Dimentions nvarchar(max);
IF OBJECT_ID('tempdb.dbo.##ALL_Dimentions', 'U') IS NOT NULL DROP TABLE ##ALL_Dimentions;
SELECT #SQL_Dimentions = 'SELECT [xxx_ID_xxx] = ROW_NUMBER() OVER (ORDER BY ' + #ListOfColumns_Dimension + '), ' + #ListOfColumns_Dimension
+ ' INTO ##ALL_Dimentions '
+ ' FROM (SELECT DISTINCT' + #ListOfColumns_Dimension + ' FROM ' + #TableName
+ ' WHERE ' + (SELECT [ColumnName] FROM #DIM_TAB WHERE [DIM_ID] = #DIM_ID) + ' IS NOT NULL ';
SELECT #DIM_ID = #DIM_ID + 1;
WHILE #DIM_ID <= (SELECT MAX([DIM_ID]) FROM #DIM_TAB)
BEGIN
SELECT #SQL_Dimentions = #SQL_Dimentions + 'AND ' + (SELECT [ColumnName] FROM #DIM_TAB WHERE [DIM_ID] = #DIM_ID) + ' IS NOT NULL ';
SELECT #DIM_ID = #DIM_ID + 1;
END
SELECT #SQL_Dimentions = #SQL_Dimentions + ' )x';
EXECUTE SP_EXECUTESQL #SQL_Dimentions;
--#######################################################################################################################
--###| Step 4 - Preparing table with all possible connections between Stable columns excluding NULLs
--#######################################################################################################################
DECLARE #StabPos_TAB TABLE ([StabPos_ID] smallint, [ColumnName] nvarchar(128))
INSERT INTO #StabPos_TAB
SELECT [StabPos_ID] = ROW_NUMBER() OVER(ORDER BY [ColumnName]), [ColumnName] FROM #ColumnListWithActions WHERE [Action] = 'S';
DECLARE #StabPos_ID smallint;
SELECT #StabPos_ID = 1;
DECLARE #SQL_MainStableColumnTable nvarchar(max);
IF OBJECT_ID('tempdb.dbo.##ALL_StableColumns', 'U') IS NOT NULL DROP TABLE ##ALL_StableColumns;
SELECT #SQL_MainStableColumnTable = 'SELECT xxx_ID_xxx = ROW_NUMBER() OVER (ORDER BY ' + #ListOfColumns_Stable + '), ' + #ListOfColumns_Stable
+ ' INTO ##ALL_StableColumns '
+ ' FROM (SELECT DISTINCT' + #ListOfColumns_Stable + ' FROM ' + #TableName
+ ' WHERE ' + (SELECT [ColumnName] FROM #StabPos_TAB WHERE [StabPos_ID] = #StabPos_ID) + ' IS NOT NULL ';
SELECT #StabPos_ID = #StabPos_ID + 1;
WHILE #StabPos_ID <= (SELECT MAX([StabPos_ID]) FROM #StabPos_TAB)
BEGIN
SELECT #SQL_MainStableColumnTable = #SQL_MainStableColumnTable + 'AND ' + (SELECT [ColumnName] FROM #StabPos_TAB WHERE [StabPos_ID] = #StabPos_ID) + ' IS NOT NULL ';
SELECT #StabPos_ID = #StabPos_ID + 1;
END
SELECT #SQL_MainStableColumnTable = #SQL_MainStableColumnTable + ' )x';
EXECUTE SP_EXECUTESQL #SQL_MainStableColumnTable;
--#######################################################################################################################
--###| Step 5 - Preparing table with all options ID
--#######################################################################################################################
DECLARE #FULL_SQL_1 NVARCHAR(MAX)
SELECT #FULL_SQL_1 = ''
DECLARE #i smallint
IF OBJECT_ID('tempdb.dbo.##FinalTab', 'U') IS NOT NULL DROP TABLE ##FinalTab;
SELECT #FULL_SQL_1 = 'SELECT t.*, dim.[xxx_ID_xxx] '
+ ' INTO ##FinalTab '
+ 'FROM ' + #TableName + ' t '
+ 'JOIN ##ALL_Dimentions dim '
+ 'ON t.' + (SELECT [ColumnName] FROM #DIM_TAB WHERE [DIM_ID] = 1) + ' = dim.' + (SELECT [ColumnName] FROM #DIM_TAB WHERE [DIM_ID] = 1);
SELECT #i = 2
WHILE #i <= (SELECT MAX([DIM_ID]) FROM #DIM_TAB)
BEGIN
SELECT #FULL_SQL_1 = #FULL_SQL_1 + ' AND t.' + (SELECT [ColumnName] FROM #DIM_TAB WHERE [DIM_ID] = #i) + ' = dim.' + (SELECT [ColumnName] FROM #DIM_TAB WHERE [DIM_ID] = #i)
SELECT #i = #i +1
END
EXECUTE SP_EXECUTESQL #FULL_SQL_1
--#######################################################################################################################
--###| Step 6 - Selecting final data
--#######################################################################################################################
DECLARE #STAB_TAB TABLE ([STAB_ID] smallint, [ColumnName] nvarchar(128))
INSERT INTO #STAB_TAB
SELECT [STAB_ID] = ROW_NUMBER() OVER(ORDER BY [ColumnName]), [ColumnName]
FROM #ColumnListWithActions WHERE [Action] = 'S';
DECLARE #VAR_TAB TABLE ([VAR_ID] smallint, [ColumnName] nvarchar(128))
INSERT INTO #VAR_TAB
SELECT [VAR_ID] = ROW_NUMBER() OVER(ORDER BY [ColumnName]), [ColumnName]
FROM #ColumnListWithActions WHERE [Action] = 'V';
DECLARE #y smallint;
DECLARE #x smallint;
DECLARE #z smallint;
DECLARE #FinalCode nvarchar(max)
SELECT #FinalCode = ' SELECT ID1.*'
SELECT #y = 1
WHILE #y <= (SELECT MAX([xxx_ID_xxx]) FROM ##FinalTab)
BEGIN
SELECT #z = 1
WHILE #z <= (SELECT MAX([VAR_ID]) FROM #VAR_TAB)
BEGIN
SELECT #FinalCode = #FinalCode + ', [ID' + CAST((#y) as varchar(10)) + '.' + (SELECT [ColumnName] FROM #VAR_TAB WHERE [VAR_ID] = #z) + '] = ID' + CAST((#y + 1) as varchar(10)) + '.' + (SELECT [ColumnName] FROM #VAR_TAB WHERE [VAR_ID] = #z)
SELECT #z = #z + 1
END
SELECT #y = #y + 1
END
SELECT #FinalCode = #FinalCode +
' FROM ( SELECT * FROM ##ALL_StableColumns)ID1';
SELECT #y = 1
WHILE #y <= (SELECT MAX([xxx_ID_xxx]) FROM ##FinalTab)
BEGIN
SELECT #x = 1
SELECT #FinalCode = #FinalCode
+ ' LEFT JOIN (SELECT ' + #ListOfColumns_Stable + ' , ' + #ListOfColumns_Variable
+ ' FROM ##FinalTab WHERE [xxx_ID_xxx] = '
+ CAST(#y as varchar(10)) + ' )ID' + CAST((#y + 1) as varchar(10))
+ ' ON 1 = 1'
WHILE #x <= (SELECT MAX([STAB_ID]) FROM #STAB_TAB)
BEGIN
SELECT #FinalCode = #FinalCode + ' AND ID1.' + (SELECT [ColumnName] FROM #STAB_TAB WHERE [STAB_ID] = #x) + ' = ID' + CAST((#y+1) as varchar(10)) + '.' + (SELECT [ColumnName] FROM #STAB_TAB WHERE [STAB_ID] = #x)
SELECT #x = #x +1
END
SELECT #y = #y + 1
END
SELECT * FROM ##ALL_Dimentions;
EXECUTE SP_EXECUTESQL #FinalCode;
From executing the first query (by passing source DB and table name) you will get a pre-created execution query for the second SP, all you have to do is define is the column from your source:
+ Stable
+ Value (will be used to concentrate values based on that)
+ Dim (column you want to use to pivot by)
Names and datatypes will be defined automatically!
I cant recommend it for any production environments but does the job for adhoc BI requests.
I modified Taryn's answer ("Pivot with unknown number of columnnames" version) to show more than 1 row in the result. This requires to have an additional "Group" column
DROP TABLE #yourtable
CREATE table #yourtable
([Id] int,[Group] int, [Value] varchar(6), [ColumnName] varchar(13))
;
INSERT INTO #yourtable
([Id],[Group], [Value], [ColumnName])
VALUES
(1,1, 'John', 'FirstName'),
(2,1, '2.4', 'Amount'),
(3,1, 'ZH1E4A', 'PostalCode'),
(4,1, 'Fork', 'LastName'),
(5,1, '857685', 'AccountNumber'),
(6,2, 'Pedro', 'FirstName'),
(7,2, '5.1', 'Amount'),
(8,2, '123456', 'PostalCode'),
(9,2, 'Torres', 'LastName'),
(10,2, '857686', 'AccountNumber')
;
;
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT ',' + QUOTENAME(ColumnName)
from #yourtable
group by [Group], ColumnName, id
having [group] = (SELECT TOP 1 MIN([Group])FROM #yourtable)
order by id
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = N'SELECT ' + #cols + N' from
(
select value, ColumnName,[Group]
from #yourtable
GROUP BY [Group],ColumnName,Value
) x
pivot
(
max(value)
for ColumnName in (' + #cols + N')
) p '
exec sp_executesql #query;
Please try
CREATE TABLE pvt (Present int, [Absent] int);
GO
INSERT INTO pvt VALUES (10,40);
GO
--Unpivot the table.
SELECT Code, Value
FROM
(SELECT Present, Absent
FROM pvt) p
UNPIVOT
(Value FOR Code IN
(Present, [Absent])
)AS unpvt;
GO
DROP TABLE pvt
One more option which could be very useful is using CROSS APPLY
-- Original data
SELECT * FROM (VALUES ('1', 1, 2, 3),('2', 11, 22, 33)) AS Stage(id,col1,col2,col3)
-- row to columns using CROSS APPLY
SELECT Stage.id,v.idd, v.colc
FROM (VALUES ('1', 1, 2, 3),('2', 11, 22, 33)) AS Stage(id,col1,col2,col3)
CROSS APPLY (VALUES ('col1', col1),('col2', col2),('col3', col3)) AS v(idd,colc)
GO
Hi all I have written the following Procedure to display the results as pivot as per the requirement
DECLARE #values AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
SELECT #values = STUFF(
(
SELECT DISTINCT ',[' + ColumnName + ']'
FROM xTable
FOR xml path ('')
),1,1,'')
SET #query = 'SELECT viewName1.*, pValues.Code, ' + #values + ' FROM
(
SELECT Column1,Column2, Column3
FROM viewname
) aliasName
PIVOT
(
MAX(value)
FOR ColumnName in (' + #values + ')
) pValues INNER JOIN viewName1 ON pValues.Code = viewname.Code'
EXEC(#query)
But when the value and column names are same in my xTable and viewName1 I am getting that error how can I resolve this. I tried with alas but I am not getting the expected result so can some one help me.
Sample is I am having a ColumnName as TopBrand in my table xTable, this can be a value in my viewName1 like for X Column TopBrand can be a value.
I think you need to have a separate list for FOR and IN clauses and the former should include the alias:
DECLARE #valuesFor AS NVARCHAR(MAX),
#valuesIn AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
SELECT #valuesFor = STUFF(
(
SELECT DISTINCT N',pValues.[' + ColumnName + ']'
FROM xTable
FOR xml path ('')
),1,1,'')
SELECT #valuesIn = STUFF(
(
SELECT DISTINCT N',[' + ColumnName + ']'
FROM xTable
FOR xml path ('')
),1,1,'')
SET #query = N'SELECT viewName1.*, pValues.Code, ' + #valuesFor + N' FROM
(
SELECT Column1,Column2, Column3
FROM viewname
) aliasName
PIVOT
(
MAX(value)
FOR ColumnName in (' + #valuesIn + N')
) pValues INNER JOIN viewName1 ON pValues.Code = viewname.Code'
EXEC(#query)
I know how to find which table has that column name, by running:
select * From INFORMATION_SCHEMA.COLUMNS Where column_name = 'column value'
What i need now, is to find which tables have that certain column data.
It doesn't matter which column it belongs, I can find it, i just don't know which table to look at.
Joining these tables is not a solution, since there are a lot of tables.
Pls. let me know if you have ideas.
Thanks.
Will this do the job for you?
declare #data varchar(50)
,#sql varchar(max)
select #data = '%test%'
create table #Temp ([Table] varchar(200), [Column] varchar(200), [Data] varchar(max))
select #sql = isnull(#sql, '') + 'insert into #Temp select ''' + sys.tables.name + ''', ''' + sys.columns.name + ''', ' + sys.columns.name + ' from [' + sys.tables.name + '] where [' + sys.columns.name + '] like ''' + #data + ''';'
from sys.tables
inner join sys.columns
on sys.columns.object_id = sys.tables.object_id
exec(#sql)
select * from #Temp order by [Table], [Column]
drop table #Temp