Select table from database where value is X - mysql

So far I've found out that this gives me a list of all the tables which has the column name "store_id" - but I only want it to select the columns if "store_id" = 4, how could I do this?
Right now I use this to find the tables which has the "store_id" column.
SELECT DISTINCT TABLE_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME IN ('store_id')
AND TABLE_SCHEMA='db1';

You can it with dynamic SQL like this
SET #sql = NULL;
SELECT GROUP_CONCAT(DISTINCT
CONCAT('SELECT ''', TABLE_NAME,
''' table_name FROM ', TABLE_NAME,
' WHERE store_id = 4')
SEPARATOR ' UNION ALL ')
INTO #sql
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME = 'store_id'
AND TABLE_SCHEMA = SCHEMA();
SET #sql = CONCAT(#sql, ' ORDER BY table_name');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Sample output:
| TABLE_NAME |
-------------|
| table1 |
Here is SQLFiddle demo
Now you can simplify things on calling end by wrapping it up into a stored procedure
DELIMITER $$
CREATE PROCEDURE list_tables(IN _column_name VARCHAR(64), IN _column_value VARCHAR(256))
BEGIN
SET #sql = NULL;
SELECT GROUP_CONCAT(DISTINCT
CONCAT('SELECT ''', TABLE_NAME, ''' table_name
FROM ', TABLE_NAME,
' WHERE ', _column_name, ' = ''', _column_value, '''')
SEPARATOR ' UNION ALL ')
INTO #sql
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME = _column_name
AND TABLE_SCHEMA = SCHEMA();
SET #sql = CONCAT(#sql, ' ORDER BY table_name');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END$$
DELIMITER ;
And use it like this
CALL list_tables('store_id', '4');
Here is SQLFiddle demo

Use IF clause in MySQL.
SELECT DISTINCT TABLE_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE
IF(store_id = 4)
COLUMN_NAME = store_id
END IF;
OR
You can use case statement.
SELECT DISTINCT TABLE_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE CASE WHEN store_id = 4
THEN COLUMN_NAME = store_id

Related

Subquery in FROM clause using information_schema.tables

I'am trying to get all tables from a database where table name contains 'logs' and get the sum last value in each table of a column named flag.
Query I tried:
Select SUM(flag) FROM (SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'db_test' AND table_name like '%logs') as c ORDER BY id DESC Limit 1;
But I'am having an issue with the subquery, I think the whole query is wrong.
I have broken this down into baby steps - nothing to stop you adjusting to taste.
drop table if exists onelog,twolog;
create table onelog (id int,flag int);
create table twolog (id int,flag int);
insert into onelog values (1,10),(2,1);
insert into twolog values (1,20),(2,1);
set #sql =
(
select group_concat(
concat('select id,flag from '
,tname, ' where id = (select max(id) from ', tname, ') union all'
)
)
from
(
select table_name tname from information_schema.tables where table_name like '%log' and table_schema = 'sandbox'
) s
)
;
set #sql = substring(#sql,1, length(#sql) - 10);
set #sql = replace(#sql,'union all,','union all ');
set #sql = concat('select sum(flag) from (', #sql , ' ) s');
#select #sql;
prepare sqlstmt from #sql;
execute sqlstmt;
deallocate prepare sqlstmt;
+-----------+
| sum(flag) |
+-----------+
| 2 |
+-----------+
1 row in set (0.001 sec)

Laravel Query with statements

This is a Query which converts data in rows, to data in columns, by declaring a variable then preparing the statement and executing the query.
Now my question is how can i convert this query to laravel query format, kindly help me.
SET #sql = NULL, #sql1 = NULL, #sql2 = NULL;
SELECT GROUP_CONCAT(
CONCAT('WHEN ''', column_name, ''' THEN `', column_name, '`')
SEPARATOR ' ')
INTO #sql1
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_schema = SCHEMA()
AND table_name = '7'
AND column_name LIKE '7%'
GROUP BY table_name;
SELECT GROUP_CONCAT(
CONCAT('SELECT ''', column_name, ''' objectid' )
SEPARATOR ' UNION ALL ')
INTO #sql2
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_schema = SCHEMA()
AND table_name = '7'
AND column_name LIKE '7%'
GROUP BY table_name;
SET #sql = CONCAT(
'SELECT m.ObjectID, m.ObjectLabel, q.Value
FROM modules_forms_objects m LEFT JOIN
(
SELECT objectid,
CASE objectid ', #sql1, ' END value
FROM `7` t CROSS JOIN
(', #sql2, '
) c
) q`enter code here`
ON m.objectid = q.objectid');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Any reason why you cannot use raw queries?
DB::select(' { Your Code Here} '); ?
or
DB::raw(' {Your Code Here} ');

MySQL min and max of each column

I can run the following to dynamically identify all decimal fields in table with many columns:
SELECT COLUMN_NAME, DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME='tbl_name' AND DATA_TYPE = 'decimal'
How would I pull the min and max value for each of those fields? e.g. final output like:
COLUMN_NAME DATA_TYPE MIN_VAL MAX_VAL
a decimal 4 22
b decimal 18 5593
c decimal 1 299
UPDATE:
Here is the final syntax I used to get this working. Maybe I missed an easier way but this is working, so thanks to Gordon Linoff for the answer.
set #sql = concat('SELECT ', #cols, ' FROM ', #t);
SELECT #sql := GROUP_CONCAT(REPLACE(REPLACE(#sql, #cols,
CONCAT('"', COLUMN_NAME, '" as TheCol', ', ', '"', DATA_TYPE, '" as TheDType', ', ',
'MIN(', COLUMN_NAME, ') as TheMin, MAX(', COLUMN_NAME, ') as TheMax'
)
),
#t, 'tbl_name') SEPARATOR ' union all '
)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME='tbl_name' AND DATA_TYPE = 'decimal';
prepare s from #sql;
execute s;
deallocate prepare s;
You need to use dynamic sql:
set #sql = 'SELECT #cols FROM #t';
SELECT #sql := GROUP_CONCAT(REPLACE(REPLACE(#sql, #cols,
CONCAT(COLUMN_NAME, ', ', DATA_TYPE, ', ',
'MIN(', COLUMN_NAME, '), MAX(', COLUMN_NAME, ')'
)
),
#t, 'tbl_name') SEPARATOR ' union all '
)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME='tbl_name' AND DATA_TYPE = 'decimal';
prepare s from #sql;
execute s;
deallocate prepare s;

Create table from a previous prepared statemt

Hi i've got something like this as part of a more complex query:
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Rather than executing the stmt itself i want to create a table from the result of the execute.
Create table A as select * from (Execute stmt)
gives me error
EDIT:
Here's the entire stuff:
Use catdatabase;
SET SESSION group_concat_max_len = 1000000;
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT('SUM(CASE WHEN columnA = "' ,columnA, '"THEN 1 ELSE 0 end) AS "' ,columnA, '"'))
INTO #sql
FROM
tableB;
SET #sql = CONCAT('SELECT columnB, Count(*) total, ', #sql, '
FROM tableA inner join tableB on tableA.columnC = tableB.columnE where tableA.columnD <> "catpoop"
GROUP BY columnB');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
As I can see you want to pivot your data and wants to save into temporary table.
I have updated your query, Please check out this:
Use catdatabase;
SET SESSION group_concat_max_len = 1000000;
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT('SUM(CASE WHEN columnA = "' ,columnA, '"THEN 1 ELSE 0 end) AS "' ,columnA, '"'))
INTO #sql
FROM
tableB;
SET #sql = CONCAT('Create temporary table temp SELECT columnB, Count(*) total, ', #sql, ' FROM tableA inner join tableB on tableA.columnC = tableB.columnE where tableA.columnD <> "catpoop"
GROUP BY columnB');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
If you get any error in this just let me know.
set #table='t2';
SET #table1 = 'test';
set #a = concat('create table ',#table,' select * from ',#table1);
prepare stmt1 from #a;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
https://dev.mysql.com/doc/refman/5.0/en/sql-syntax-prepared-statements.html
updated:
SET SESSION group_concat_max_len = 1000000;
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT('SUM(CASE WHEN columnA = "' ,columnA, '"THEN 1 ELSE 0 end) AS "' ,columnA, '"'))
INTO #sql
FROM
tableB;
SET #sql = CONCAT('SELECT columnB, Count(*) total, ', #sql, '
FROM tableA inner join tableB on tableA.columnC = tableB.columnE where tableA.columnD <> "catpoop"
GROUP BY columnB');
set #new_sql = concat ('create table A',#sql);
PREPARE stmt FROM #new_sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

how to select only non empty columns of a table from database

I have a table with 46 columns in my database, In these 46 columns 25 or 26 are mostly empty.
when I select all columns by some condition I want only those column will select which have some data in it
You can try this query to show you the not null columns' names:
SET group_concat_max_len = 4294967295;
SELECT GROUP_CONCAT(CONCAT(
' SELECT ',QUOTE(COLUMN_NAME),
' FROM table_name',
' WHERE `',REPLACE(COLUMN_NAME, '`', '``'),'` IS NOT NULL',
' HAVING COUNT(*)'
) SEPARATOR ' UNION ALL ')
INTO #sql
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'table_name';
PREPARE stmt FROM #sql;
EXECUTE stmt;
SQL Fiddle
And then just excute these columns manualy:
SELECT column_name3, column_name8 FROM Table_Name;
SQL Fiddle