What i am trying to do looks like the following
insert into user_audit
( SELECT COLUMN_NAME
FROM information_schema.columns
WHERE TABLE_NAME='user' and TABLE_SCHEMA = database() )
VAlUES ( SELECT * FROM `user` where id = NEW.id )
Insert into user_audit the column name of user table and the values of user table
Thanks for helping
Can you please try the following Dynamic SQL: It might help
declare #insertquery nvarchar(1000)
Declare #ColumnNames varchar(2000)
select #ColumnNames = COALESCE(#ColumnNames + ', ', '') + COLUMN_NAME
from
INFORMATION_SCHEMA.COLUMNS
where
TABLE_NAME='user' and TABLE_SCHEMA = database();
set #insertquery = N'insert into user_audit(' + #ColumnNames + ') SELECT * FROM `user` where id = NEW.id;
sp_executesql #insertquery
Related
I have a table called tbl_site with 50 columns. I want to write some SQL code that will count the number of distinct values and the number of null values for each column without having to run a statement for each column.
I understand this would possibly include running a nested query to information_schema.columns but I am unsure on how to construct the query further. Also null values would include values that are '' and ' ' if possible.
The desired output would be the following:
Column | Distinct | Null
site_id | 100 | 0
sitearea_id | 12 | 0
site_area | 54 | 5
etc....
Try a mixture of count distinct and sum case:
SELECT Column, count(distinct Column) as 'Distinct'
,sum(case when Column is null then 1 else 0 end) as 'Null'
FROM tbl_site
GROUP BY 1
Yeah, I noticed it's MySQL after i made a script for SQL Server ... but anyway here is the code in case someone needs it ... or if you get idea from it how to do it
declare #position int = 1,
#sql nvarchar(max),
#columnCnt int,
#currentColumn nvarchar(50),
#TableName nvarchar(50) = 'YourTableName',
#DBName nvarchar(50) = 'YourDbName';
if (OBJECT_ID('tempdb..#MyRowCount')) IS NOT NULL DROP TABLE #MyRowCount
CREATE TABLE #MyRowCount (ColumnName nvarchar(50), DistinctCount int, NullCount int)
set #columnCnt = (select MAX(ORDINAL_POSITION) from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = #TableName and TABLE_CATALOG = #DBName)
WHILE (#position <= #columnCnt)
BEGIN
set #currentColumn = (select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = #TableName and
TABLE_CATALOG = #DBName and
ORDINAL_POSITION = #position)
set #sql = 'INSERT INTO #MyRowCount (ColumnName, DistinctCount, NullCount)
SELECT ''' + #currentColumn + ''',
(SELECT COUNT(DISTINCT [' + #currentColumn + ']) FROM ' + #TableName + ' where [' + #currentColumn + '] IS NOT NULL),
(SELECT COUNT(*) FROM ' + #TableName + ' where [' + #currentColumn + '] IS NULL)';
-- print #sql;
execute (#sql);
set #position = #position + 1;
END
SELECT * FROM #MyRowCount
In MySQL, you can construct the query using:
set #sql = '
select ''[column]'' as col, count(distinct "[column]"), sum("[column]" is null)
from [table] t
';
select group_concat(replace(replace(#sql, '[table]', table_name), '[column]', column_name) separator ' union all ')
from information_schema.columns
where table_name = ?;
The caveat to this approach is that you need to be sure that your group_concat maximum length value is long enough (the default of 1024 won't get you very far).
Then, you can either copy the query to use prepare/execute to run it.
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 stored procedure that should execute the sample code:
IF EXISTS (
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME IN ('TB1', 'TB2', 'TB3')
AND COLUMN_NAME = 'COL'
AND table_schema = 'TestDB'
GROUP BY TABLE_NAME
HAVING count (TABLE_NAME) = 3
)
THEN
/*Used for debugging*/
SELECT 'Tables EXIST' INTO msg;
ELSE
/*Used for debugging*/
SELECT 'NON-EXISTENT TABLES !' INTO msg;
END IF
Basically, I want the above snippet to select all specified tables that has a column named 'COL'. I only want to do this using information_schema, nothing else.
Upon check, the test statement (IF EXISTS) always returned false. That is, the ELSE statement always execute even though my three test tables (TB1, TB2 and TB3) have the COL field. What sin am I commiting ?
You could do it as a function like this:
Function:
CREATE DEFINER=`root`#`localhost` FUNCTION `new_function`() RETURNS varchar(64) CHARSET utf8
BEGIN
declare cnt int;
declare msg varchar(64);
select count(*) from (
select distinct
table_name
from information_schema.columns
where table_name in ('TB1', 'TB2', 'TB3')
and column_name = 'COL'
and table_schema = 'TestDB'
) tbls into cnt;
if cnt = 3 then
select 'tables exist' into msg;
else
select 'tables do not exists' into msg;
end if;
RETURN msg;
END
And then run this:
create schema TestDB;
use TestDB;
create table TB1(
COL int
);
create table TB2(
COL int
);
create table TB3(
COL int
);
select new_function();
This will return:
Tables Exist
Something parallel to this should work
select distinct
table_name
from information_schema.columns
where column_name = 'CHARACTER_SET_NAME'
and table_name in ('CHARACTER_SETS', 'COLLATIONS', 'COLUMNS', 'TRIGGERS', 'FOO', 'BAR')
;
where you have this
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME IN ('TB1', 'TB2', 'TB3')
AND COLUMN_NAME = 'COL'
AND table_schema = 'TestDB'
GROUP BY TABLE_NAME
HAVING count (TABLE_NAME) = 3
)
i.e. this:
select distinct
table_name
from information.schema.columns
where table_name in ('TB1', 'TB2', 'TB3')
and column_name = 'COL'
and table_schema = 'TestDB'
and if you want to make sure all three tables exist and have a 'COL' column write a conditional to check that this evaluates to 3
select count(*) from (
select distinct
table_name
from information.schema.columns
where table_name in ('TB1', 'TB2', 'TB3')
and column_name = 'COL'
and table_schema = 'TestDB'
) tbls
;
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
I have a bunch of columns in a mysql table whose names begin with 'X_' (for example: X_N, X_Pad, X_Server etc). Now, these columns can be null.
I want to find out which column beginning with 'X_' is NOT NULL the most.
COUNT(expr)
Returns a count of the number of non-NULL values of expr in the rows
retrieved by a SELECT statement.
The following query will return not-null counts for each column:
SELECT
COUNT(*) AS Total,
COUNT(X_N) AS NNC_N,
COUNT(X_Pad) AS NNC_Pad
FROM table;
You can use this query to get the list of matching columns from a table:
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = '<database_name>'
AND TABLE_NAME = '<table_name>'
AND COLUMN_NAME LIKE 'x\_%';
-- Output:
-- X_N
-- X_Pad
-- X_Server
You can use this query to build a query:
SELECT CONCAT('SELECT ', GROUP_CONCAT('COUNT(`', COLUMN_NAME, '`) AS `NNC of ', COLUMN_NAME, '`'), ' FROM `', TABLE_NAME, '`')
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = '<database_name>'
AND TABLE_NAME = '<table_name>'
AND COLUMN_NAME LIKE 'x\_%';
-- Output (added whitespace for readability):
-- SELECT
-- COUNT(`X_N`) AS `NNC of X_N`,
-- COUNT(`X_Pad`) AS `NNC of X_Pad`,
-- COUNT(`X_Server`) AS `NNC of X_Server`
-- FROM `<table_name>`
Alternate:
SELECT GROUP_CONCAT('SELECT \'', COLUMN_NAME, '\' AS `Col`, COUNT(`', COLUMN_NAME , '`) AS `NNC` FROM `', TABLE_NAME , '`' SEPARATOR ' UNION ALL ')
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = '<database_name>'
AND TABLE_NAME = '<table_name>'
AND COLUMN_NAME LIKE 'x\_%';
-- Output (added whitespace for readability):
-- SELECT 'X_N' AS `Col`, COUNT(`X_N`) AS `NNC` FROM `<table_name>` UNION ALL
-- SELECT 'X_Pad' AS `Col`, COUNT(`X_Pad`) AS `NNC` FROM `<table_name>` UNION ALL
-- SELECT 'X_Server' AS `Col`, COUNT(`X_Server`) AS `NNC` FROM `<table_name>`
select count(X_N), count(X_Pad), count(X_Server) from db.tbl;
can be ok.
If you just need a method to generate this SQL, you can use
SELECT CONCAT("select ", GROUP_CONCAT("count(",column_name, ")"), " from ", table_schema, '.', table_name)
FROM information_schema.columns
WHERE table_schema='db' AND table_name='tbl' AND column_name LIKE 'X\_%';
Something like this perhaps? (untested)
SELECT
(SELECT COUNT(id) FROM My_Table WHERE X_1 != NULL) as x1,
(SELECT COUNT(id) FROM My_Table WHERE X_2 != NULL) as x2,
(SELECT COUNT(id) FROM My_Table WHERE X_3 != NULL) as x3,
(SELECT COUNT(id) FROM My_Table WHERE X_4 != NULL) as x4;