mysql, how to drop tables that the table name starts with digits - mysql

I have 1200 tables in my database, and the table names of half of them are start with digits, just looks like this
mysql> SHOW TABLES;
1000_quarterly_1000
1001_quarterly_1001
...
quarterly_1000
quarterly_1001
....
And I want drop all the tables the name of which start with digits, for example table 1000_quarterly_1000 must be dropped. And since tables have been dropped from the current database and I want to store them to other database I have defined.
How can I write mysql query to do this, since I can use Python to do this, but mysql query can be better.

If you want to drop the tables in one statement, you can construct the statement as:
select concat('drop table ', group_concat(t.table_schema, '.', t.table_name separator ', '))
from information_schema.tables
where left(t.table_name, 1) between '0' and '9';
You can then try to execute a command:
declare #sql varchar(65000);
select #sql := concat('drop table ', group_concat(t.table_schema, '.', t.table_name separator ', '))
from information_schema.tables
where left(t.table_name, 1) between '0' and '9';
prepare s from #sql;
execute s;

select concat('drop table ',t.table_schema,'.',t.table_name,';') drop_ddl
from information_schema.tables t where t.table_name rlike '[0-9].'

Related

How to remove a prefix name from every table name in specific MySQL database

All tables in specific MySQL database, for example my_db, start with a prefix which its length is 17 character. I want to remove prefix from name of all tables. How I can do this?
improved hasanghaforian's answer...
removed extra concat functions.. still produces same output
select concat('RENAME TABLE ', table_name, ' TO ' , substr(table_name,18) , ' ; ' ) from information_schema.tables where table_schema = 'my_db';
I added where table_schema = 'my_db' to the statement that is described here to get statements for renaming all tables in my_db database, instead of renaming all tables of all databases in MySQL server instance:
select concat('RENAME TABLE ', concat(table_name, concat(' TO ', concat(substr(table_name, 18), ';')))) from information_schema.tables where table_schema = 'my_db';
Pay attention that the length of prefix was 17 and I used 18 in substr command.

Please explain these SQL statements

Please explain me the below example
SELECT GROUP_CONCAT(COLUMN_NAME)
FROM information_schema.`COLUMNS` C
WHERE table_name = 'table_name'
AND COLUMN_NAME =('columns_name') INTO #COLUMNS;
SET #table = 'table_name';
SET #s = CONCAT('SELECT ',#columns,' FROM ', #table);
PREPARE stmt FROM #s;
This pattern is all about creating dynamic (prepared in MySQL parlance) queries based on the names of columns in a particular table. INFORMATION_SCHEMA is a built-in database with read-only tables describing all the tables in all databases on the MySQL server.
The first query in your sequence retrieves a text string in the local variable #COLUMNS with a value like
id,name,value,description
for a table named table_name with those four columns.
The third one retrieves a string in the local variable #s with a value containing a query like
SELECT id,name,value,description FROM table_name
The fourth one, PREPARE, gets ready to do EXECUTE stmt, which runs the query. You can read about PREPARE and EXECUTE here.
The whole sequence of queries in your question does almost exactly the same thing as SELECT * FROM table_name.
There's a defect in your first query. You should add AND TABLE_SCHEMA = DATABASE() to its WHERE clause. Otherwise, you may pick up columns from tables named table_name in multiple databases.

Mysql sum all columns starting with some letters

I am trying add one column in my Mysql database that sums all the columns starting by 'tokenvalid' which can take the value of 1 or 0.
And let's say I have 50 columns like that in my database (i.e. tokenvalid1, tokenvalid2 ...., tokenvalide50) with other columns between.
Please find below the code I would like to implement. I know that is not correct at all but it is just to give you an idea of what I am trying to do.
Thank you for your help!
'SELECT *, sum(column_name LIKE "tokenvalid"%) as total FROM points WHERE 1'
This post should help you. The post describes how to get the columns and then query for results.
MySQL Like statement in SELECT column_name
Something like this should help you.
SET #colname = (SELECT GROUP_CONCAT(`column_name`) from INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='points' AND `column_name` LIKE 'tokenvalid%');
SET #table = 'points';
SET #query = CONCAT('SELECT SUM(',#colname,') FROM ', #table);
PREPARE stmt FROM #query;
EXECUTE stmt;
Similar to this answer by RocketDonkey
If the string is in your external application (like PHP), sure, just construct the MySQL statement.
If the string is inside a MySQL table, you can't. MySQL has no eval() or such function. The following is impossible:
Suppose you have a table 'queries' with a field "columnname" that refers to one of the column names in the table "mytable". There might be additional columns in 'queries' that allow you to select the columnname you want...
INSERT INTO queries (columname) VALUES ("name")
SELECT (select columnname from queries) from mytable
You can however work with PREPARED STATEMENTS. Be aware this is very hacky.
SELECT columnname from queries into #colname;
SET #table = 'mytable';
SET #s = CONCAT('SELECT ',#colname,' FROM ', #table);
PREPARE stmt FROM #s;
EXECUTE stmt;

SELECT column_name FROM (SELECT table_name FROM TABLE_OF_TABLES)

I have a table of tables called TABLES. TABLES has a column TABLE_NAME.
For each TABLE_NAME there exists a table in the database. All of these tables are structured the same.
Ultimately I would like to UNION columns from each of these tables. But I'm not getting close to that objective.
I am stuck on the following query:
SELECT column_name FROM (SELECT table_name FROM TABLES) T;
The error returned is "ERROR 1054 (42S22): Unknown column 'column_name' in 'filed list'.
I haven't seen a good representation of SELECT...FROM (SELECT...FROM)
Any help is most appreciated.
There is no way to achieve this with a static query. If you really need this for some reason you have to use dynamic SQL
SET #sql = NULL;
SELECT GROUP_CONCAT(CONCAT('SELECT column_name FROM `', table_name, '`') SEPARATOR ' UNION ALL ')
INTO #sql
FROM tables;
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Here is SQLFiddle demo
To simplify things on the calling side you can always wrap it in a stored procedure.
You can try
SELECT column_name FROM (SELECT column_name FROM TABLES) T;
OR
SELECT column_name FROM (SELECT * FROM TABLES) T;

MySQL bulk drop table where table like?

DROP TABLE (
SELECT table_name
FROM information_schema.`TABLES`
WHERE table_schema = 'myDatabase' AND table_name LIKE BINARY 'del%');
I know this doesn't work! What is the equivalent for something like this in SQL? I can whip out a simple Python script to do this but was just wondering if we can do something with SQL directly. I am using MySQL. Thank you!
You can use prepared statements -
SET #tables = NULL;
SELECT GROUP_CONCAT('`', table_schema, '`.`', table_name,'`') INTO #tables FROM information_schema.tables
WHERE table_schema = 'myDatabase' AND table_name LIKE BINARY 'del%';
SET #tables = CONCAT('DROP TABLE ', #tables);
PREPARE stmt1 FROM #tables;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
It will generate and execute a statement like this -
DROP TABLE myDatabase.del1, myDatabase.del2, myDatabase.del3;
A minor improvement to #Devart's answer:
SET #tables = NULL;
SELECT GROUP_CONCAT(table_schema, '.`', table_name, '`') INTO #tables FROM
(select * from
information_schema.tables
WHERE table_schema = 'myDatabase' AND table_name LIKE 'del%'
LIMIT 10) TT;
SET #tables = CONCAT('DROP TABLE ', #tables);
select #tables;
PREPARE stmt1 FROM #tables;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
This script should be executed repeatedly until the console's output is NULL
The changes are:
backtick (`) wrapping the table name (if it contains non standard characters)
added a LIMIT to avoid the truncation issue I commented about
added a "print" (select #tables;) to have some kind of control when to stop executing the script
If you just need to quickly drop a bunch of tables (not in pure SQL, so not directly answering this question) a one line shell command can do it:
echo "show tables like 'fsm%'" | mysql | tail +2 | while read t; do echo "drop table \`$t\`;"; done | mysql
I found it useful to add an IFNULL to Devart's solutions to avoid generating an error if there are no tables matching the query.
SET #tables = IFNULL(CONCAT('DROP TABLE ', #tables),'SELECT NULL;');
In addition to #Devart's answer:
If you have many tables, you may need to set group_concat_max_len:
SET group_concat_max_len = 4096;
You can do this quickly and easily if you have phpMyAdmin available and the requirement is to drop tables with a specific prefix. Go to the database you want, and show the list of all the tables. Since tables are shown in alphabetic order, the tables with the prefix for deletion will all appear together. Go to the first one, and click the tick box on the left hand side. Then scroll down to the last table with the prefix, hold down shift, and click the tick box. That results in all the tables with the prefix being ticked. Go to the bottom of the list, and select the action drop for all selected tables. Go through with the deletion, checking that the SQL generated looks right!