MySQL min and max of each column - mysql

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;

Related

How to print more than one values in Pivot Table?

I Have a table Attendances
and then I Make a Report using this Query
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(case when `tanggal` = ''',
`tanggal`,
''' then `in_time` end) AS `',
`tanggal`, '`'
) ORDER BY `id_employee` ASC SEPARATOR ',\n'
) INTO #sql
FROM `attendances` ;
SET #sql2 = CONCAT('SELECT id_employee, ', #sql, ' FROM attendances GROUP BY id_employee');
PREPARE stmt FROM #sql2;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Output Query :
Question : I Want To Print in_time and out_time after clause then ? Is it Possible ?
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(case when `tanggal` = ''', `tanggal`, ''' then CONCAT(in_time,''-'', out_time) end) AS `', `tanggal`, '`'
) ORDER BY `id_employee` ASC SEPARATOR ',\n'
) INTO #sql
FROM `attendances` ;
SET #sql2 = CONCAT('SELECT id_employee, ', #sql, ' FROM attendances GROUP BY id_employee');
PREPARE stmt FROM #sql2;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

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

Unable to pass parameter value in Concat select Prepared statements

I found the stored procedure does not execute only this portion:
SET #sql
= CONCAT('SELECT TraineeID, ', #sql, '
from tbl_submit_coursefee c
where c.BatchID='BID'
group by c.TraineeID');
in where clause '' quotes do not allow and without quotes query return empty but if I put the parameter value in where clause straight then it works. I'm really stack with this.
Here is my prepared statement (working fine):
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT ('MAX(IF(BillNo = ''', BillNo, ''', CRA, NULL)) AS `Inv.', BillNo, '`')
) INTO #sql
FROM tbl_submit_coursefee
WHERE BatchID="ID-Welding/FMMTTC-01M/R8/01";
SET #sql
= CONCAT('SELECT TraineeID, ', #sql, '
from tbl_submit_coursefee c
where c.BatchID="ID-Welding/FMMTTC-01M/R8/01"
group by c.TraineeID');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
when put this statement in a stored procedure (not working):
DELIMITER ##
DROP PROCEDURE GetRetainment ##
CREATE PROCEDURE vtproject.GetRetainment
(IN `BID` VARCHAR(100))
BEGIN
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT ('MAX(IF(BillNo = '', BillNo, '', CRA, NULL)) AS `Inv.', BillNo, '`')
) INTO #sql
FROM tbl_submit_coursefee
WHERE BatchID=BID;
SET #sql
= CONCAT('SELECT TraineeID, ', #sql, '
from tbl_submit_coursefee c
where c.BatchID='BID'
group by c.TraineeID');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END ##
DELIMITER ;
If I select #sql before prepare stmt FROM #sql then output as below:
SELECT TraineeID, MAX(IF(BillNo = 1, CRA, NULL)) AS `Inv.1`,MAX(IF(BillNo = 2, CRA, NULL)) AS `Inv.2`,MAX(IF(BillNo = 3, CRA, NULL)) AS `Inv.3`,MAX(IF(BillNo = 4, CRA, NULL)) AS `Inv.4`,MAX(IF(BillNo = 5, CRA, NULL)) AS `Inv.5`,MAX(IF(BillNo = 6, CRA, NULL)) AS `Inv.6`,MAX(IF(BillNo = 7, CRA, NULL)) AS `Inv.7` from tbl_submit_coursefee c where c.BatchID=BID group by c.TraineeID
you need to escape the quotes,
like this :
SET #sql
= CONCAT('SELECT TraineeID, ', #sql, '
from tbl_submit_coursefee c
where c.BatchID=''',BID,'''
group by c.TraineeID');
according with doc : http://dev.mysql.com/doc/refman/5.7/en/string-literals.html
I found the solution in another way myself.
BEGIN
SET #sql = NULL;
SET #bid=BID;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT ('MAX(IF(BillNo = ', BillNo, ', CRA, NULL)) AS `Inv.', BillNo, '`')
) INTO #sql
FROM tbl_submit_coursefee
WHERE BatchID=#bid;
SET #sql
= CONCAT('SELECT TraineeID, ', #sql, '
from tbl_submit_coursefee c
where c.BatchID=#bid
group by c.TraineeID');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END

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

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