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

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

Related

mySQL query across multiple schemas

I have a multi-schema structure (same table across all schemas).
Here is how I can fetch all the schemas:
select table_schema from information_schema.tables where table_name = 'messages' and TABLE_TYPE = 'BASE TABLE'
This query is for a join between 'messages' table across two tables-
select *, '1' as customer from customer_1.messages union select *, '2' as customer from customer_2.messages
How do I use the perform the above query for all the schemas from the first query? Need not be a join. Could be anything that helps me return the results across all schemas.
Note: There could be 5000-10000 schemas
DELIMITER ##;
CREATE PROCEDURE join_all_data()
BEGIN
SET #counter := 0;
SELECT GROUP_CONCAT('select *, ',
#counter := #counter + 1,
' as customer from ',
table_schema,
'.messages'
SEPARATOR ' UNION ALL ')
FROM information_schema.tables
WHERE table_name = 'messages'
AND table_type = 'BASE TABLE'
INTO #sql;
PREPARE stmt FROM #sql;
EXECUTE stmt;
DROP PREPARE stmt;
END
##;
DELIMITER ;
CALL join_all_data;

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} ');

put results of execute statement into table in MySQL

At MySQL pivot efficiency
I was wondering how to pivot a table of stock prices in MySQL. The consensus seems to be that this is not a good thing to do. I originally wanted each column to be an ID number and each row to be a date. I got much more speed by making each column a date and each row an ID number:
SET ##group_concat_max_len = 1000000;
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(IF(ddate = ',
'ddate',
',closing_price, NULL)) AS ''',
DATE_FORMAT(ddate,'%Y%m%d'),''''
)
) INTO #sql
FROM rawdatatable;
SET #sql = CONCAT('SELECT idnum , ', #sql, ' FROM rawdatatable GROUP BY idnum');
SELECT #sql;
PREPARE stmt FROM #sql;
EXECUTE stmt;
Is there any way to put the results of the EXECUTE statement into a table, where each column name is a different ddate?
Change this line
SET #sql = CONCAT('SELECT idnum , ', #sql, ' FROM rawdatatable GROUP BY idnum');
to
SET #sql = CONCAT('CREATE TABLE blah AS SELECT idnum , ', #sql, ' FROM rawdatatable GROUP BY idnum');
Try to put the result into a temp table like #Desolator say. Something like this in MySQL console
mysql>CREATE TABLE temp_result AS
SELECT * FROM rawdatatable
WHERE ...;

Select table from database where value is X

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

resultset of particular query

I have this query. When I execute I got Query statement but I want result set of this query.
My query is:
SELECT CONCAT('select * from ', table_name, ' union all ') AS CUSTOMQUERY
FROM information_schema.tables
WHERE table_name LIKE '%custom%'
I get this result
select * from custom_70006 union all
select * from custom_704306 union all
select * from custom_700436 union all
select * from custom_7000643 union all
select * from custom_7000634 union all
select * from custom_700046 union all
select * from custom_700063 union all
select * from custom_700062 union all
But I want result set of this particular column with corresponding data and last union all should remove.
Please help me with relevant query.
I think this is what you are looking for:
SET GLOBAL group_concat_max_len = 4294967295;
SELECT #query1 := GROUP_CONCAT(CONCAT('SELECT * FROM ', table_name) SEPARATOR
' UNION ALL ') AS CUSTOMQUERY
FROM INFORMATION_SCHEMA.tables
WHERE TABLE_SCHEMA = SCHEMA()
AND table_name LIKE '%custom%';
PREPARE stmt FROM #query1; EXECUTE stmt; DEALLOCATE PREPARE stmt;
Example: SQLFiddle
or modify your query as:
SELECT #query1 := CONCAT('select * from ', table_name, ' union all ') AS
CUSTOMQUERY
FROM information_schema.tables
WHERE table_name LIKE '%custom%'
to remove last 'union all' string from your query:
SET #query1 = TRIM(TRAILING 'union all' FROM TRIM(#query1));
PS: Default value of group_concat_max_len is only 1024. So you need to set it to higher value otherwise the output of your query will get stripped and you may get syntax error.