I'm trying to select all columns except one, so I'm using this:
select COLUMN_NAME
from information_schema.COLUMNS
where TABLE_NAME='report' and COLUMN_NAME != 'date';
It returns me the correct result, but when I try to apply it using:
select
(
select COLUMN_NAME
from information_schema.COLUMNS
where TABLE_NAME='report' and COLUMN_NAME != 'date'
)
from report limit 1;
It gives an error of ERROR 1242 (21000): Subquery returns more than 1 row
I tried to group_concat it but it returns just the columns (query):
select
(
select group_concat(COLUMN_NAME)
from information_schema.COLUMNS
where TABLE_NAME='report' and COLUMN_NAME != 'date'
)
from risk_assessment.report limit 1;
| (select group_concat(COLUMN_NAME) from information_schema.COLUMNS where TABLE_NAME='report' and COLUMN_NAME != 'date') |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| id,ref,creator,status,username,title,site,location,comment,id,status,type,chemical_name,description,title,creator,frequency,location,form,storage,comments,comments_tick,username |
What should I change?
There is no syntax for that in MariaDB. You cannot do something like (select * except x from table) in a single statement.
However, you can do it via few steps:
SET #sql =
CONCAT('SELECT ',
(SELECT
GROUP_CONCAT(COLUMN_NAME)
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_SCHEMA = '<schema>'
AND TABLE_NAME = '<table>'
AND COLUMN_NAME NOT IN ('<column>')),
' FROM <table>');
PREPARE s FROM #sql;
EXECUTE s;
Related
I'm trying to encode all columns of a found row in a table.
I've tried:
Get the columns (Let's call this query0):
-- This returns `column_0`,`column_1`...
SELECT CONCAT('`', GROUP_CONCAT(
DISTINCT COLUMN_NAME
SEPARATOR '`,`'
), '`')
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'database_name' AND TABLE_NAME = 'table_name')
Concat the columns from query0 above (Let's call this query1):
SELECT CONCAT(query0)
FROM table_name
WHERE column_0 = condition
Encode:
SELECT ENCODE((query1), 'my_key');
This doesn't work.
With mysql 8 works
SELECT
AES_ENCRYPT(names, UNHEX(SHA2('My secret passphrase',512)))
FROM
(SELECT
names
FROM
(SELECT CONCAT('`', GROUP_CONCAT(
COLUMN_NAME
SEPARATOR '`,`'
), '`') names
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'testdb' AND TABLE_NAME = 'r') t1
Where names LIKE '%authorid%') t2
;
With mysql 5.x
SELECT
ENCRYPT(names, 'My secret passphrase')
FROM
(SELECT
names
FROM
(SELECT CONCAT('`', GROUP_CONCAT(
COLUMN_NAME
SEPARATOR '`,`'
), '`') names
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'hotel') t1
Where names LIKE '%title%') t2
;
The database name and Tablename you have to change and Where names LIKE '%Colum_name%' the Coulmn_name too
How can I get a table name by his position(row)? I got many tables.
For example in columns to find from a table it works this way:
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'database name here'
AND TABLE_NAME = 'table name here'
AND ORDINAL_POSITION = 2;
I need something like this only to find table name by their position(row) in the database.
Using MySQL.
Thanks.
If I understand you correctly, you need something like that
SELECT position, TABLE_NAME
FROM (
SELECT #row := #row +1 AS position, TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
JOIN (
SELECT #row :=0
)r
WHERE TABLE_SCHEMA = 'TABLE_SCHEMA here'
)tmp
WHERE position =5
and a different approach
SET #row =0;
SELECT TABLE_NAME
FROM (
SELECT #row := #row +1 AS position, TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'TABLE_SCHEMA here'
)tmp
WHERE position =5
Looks like you want something like that:
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'database name here'
AND TABLE_NAME = (
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'database name here'
ORDER BY CREATE_TIME ASC
LIMIT 1 -- take one
OFFSET 1 -- after 1st row
)
This will return all colums from the table that was created as second table for that DB.
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 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;
Alright, I'm going to make this quick. Below I have a select showing me all the column_names that have a tinyint data_type. With the data it returns below, I need to write an enclosing query selecting from my_table and change the output of the SELECT data, I suspect by using CASE when a tinyint is 0 to No, and 1 to Yes.
SELECT
COLUMN_NAME
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
table_name = 'my_table'
AND DATA_TYPE = 'tinyint'
Thanks!
Your query in a sample:
create table a ( i tinyint, b char(5));
SELECT
COLUMN_NAME,
case DATA_TYPE
when 'tinyint' then 'Yes'
else 'No'
end
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
table_name = 'a';
Results
EDITED because OP has lost the faith.
Hi bigman, Belive me you don't want! Ok ... welcome to dark side of dynamic sql:
create table a ( i tinyint, b char(5));
insert into a values (1,'si'),(0,'no');
SELECT #a :=
concat(
'select ',
group_concat(
case DATA_TYPE
when 'tinyint' then concat(
'if( ' ,
COLUMN_NAME ,
' = 0, \'No\', \'Yes\' )'
)
else COLUMN_NAME
end
),
' from ',
table_name ,
';'
)
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
table_name = 'a';
PREPARE stmt FROM #a;
EXECUTE stmt;
Results
| IF( I = 0, 'NO', 'YES' ) | B |
---------------------------------
| Yes | si |
| No | no |