How to cast value as JSON in MariaDB? - json

I want to extract a JSON with table name and columns inside each table.
Here is my SQL:
SELECT
JSON_OBJECTAGG(table_name, columns)
FROM (
SELECT
table_name,
JSON_OBJECTAGG(column_name, data_type) as columns
FROM `COLUMNS`
WHERE
`TABLE_SCHEMA` = 'my_db'
GROUP BY table_name
) table_columns
The problem is in JSON_OBJECTAGG(table_name, columns), columns became string. How to cast it as JSON?

Use JSON_EXTRACT(column_value_in_json, '$')
SELECT
JSON_OBJECTAGG(table_name,
JSON_EXTRACT(
columns,
'$'
)
)
FROM (
SELECT
table_name,
JSON_OBJECTAGG(column_name, data_type) as columns
FROM `COLUMNS`
WHERE
`TABLE_SCHEMA` = 'my_db'
GROUP BY table_name
) table_columns

Related

Encode all columns

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

Getting table name by position(row) from database

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.

Most graceful way to select a row where multiple fields are NULL in MySQL

I have a table where most rows are sprinkled with NULLs....but I only want to match those particular rows that hold nothing but NULLs, except for 2 or 3 columns.
Something like
SELECT *
FROM sometable
WHERE
ALL(col1, col2, col3) IS NULL;
doesn't work.
Do I really have to write
WHERE
co1 IS NULL
AND
col2 IS NULL
...
AND col150 IS NULL
all the way out??
I am afraid there's an easier way in doing this.
But you can take help from
INFORMATION_SCHEMA.COLUMNS
table.
You can get all the column names of a table by this query.
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'YOUR_DATABASE_NAME'
AND TABLE_NAME = 'YOUR_TABLE_NAME';
You can modify this query to make it use in your case.
SELECT
SUBSTRING(
GROUP_CONCAT(
(
CASE
WHEN COLUMN_NAME NOT IN ('COL1','COLN') THEN
CONCAT(
COLUMN_NAME,
' IS NULL AND '
)
ELSE
''
END
) SEPARATOR ''
),
1,
LENGTH(
GROUP_CONCAT(
(
CASE
WHEN COLUMN_NAME NOT IN ('ID') THEN
CONCAT(
COLUMN_NAME,
' IS NULL AND '
)
ELSE
''
END
) SEPARATOR ''
)
) - 4
)
FROM
INFORMATION_SCHEMA. COLUMNS
WHERE
TABLE_SCHEMA = 'YOUR_DATABASE'
AND TABLE_NAME = 'YOUR_TABLE';
The above query will generate a string like 'COL2 IS NULL AND COL3 IS NULL'
Thus you can grab this string and put it in the where condition of your original query.
N:B: Mention only those columns IN THE WHERE CLAUSE [[CASE WHEN COLUMN_NAME NOT IN ('COL1','COLN')]] which are not supposed to check NULLABILITY.

Count all MySQL tables with similar column name

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
;

how to find number of times a column is not null in mysql?

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;