(My)SQL: Wildcard in FROM clause? - mysql

I have a database with about 200 tables, and need to do a query on all tables containing a certain column (creation_date), but not all tables have that column. SELECT * FROM * WHERE creation_date>=42 obviously doesn't work, but what would be the best way of doing it?

SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_DEFAULT, TABLE_NAME,
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'tbl_name'
[AND table_schema = 'db_name']
[AND column_name ='creation_date']
copied directly from MySQL - you need to loop thru these system tables and the list will contain those ...
then you can build your SQL statements and be sure that they work ...

You could build a dynamic SQL query from metadata. I would approach this like:
Get a list of tables
For each table,
See if the table has the column creation_date
If it does, add your query on this table to the dynamic query
Union the results together
You might also be able to create a view on the multiple tables. Then you can just query the view.

You can try to include the table you want to query like so:
SELECT * FROM table1 a, table2 b WHERE a.creation_date>=42
You cannot use a wildcard in the from. In the way as shown above you can specify on which tables the where clause must apply. You can than leave out the ones that don't have the column.
So in the example query, table1 (alias a) has the column, and table2 (alias b) does not.

Related

Getting all table names which contains a specific keyword inside itself

I have a database which has 180 tables in it. Going through all of them one by one would be wasting my time.
The problem I am facing, is that I want to search a specific keyword from all tables and columns. So let's say that I got a database d with tables t1, t2, and so on, all tables have different column names and the string which I want to see must be LIKE '%connect%'.
To clarify, the %connect% must be inside the table contents (i.e. inside a row of a table).
If this is not possible by a single query, maybe you can point me into the right direction how to do this programmatically.
Table's names:
select t.table_name from information_schema.tables t where t.table_name like '%connect%';
Column's names:
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'my_database' AND TABLE_NAME = 'my_table';

Is there easier syntax for joining MySQL tables based on all columns?

I have two tables with many columns (~50). Is there a way to join these tables using each column without explicitly naming each one in each table?
SELECT * from A
JOIN B
WHERE A.column1=B.column1
AND A.column2=B.column2
AND A.column3=B.column3
...
...
...
AND A.column50=B.column50
There are many questions about various joins on stack (e.g. this one on multiple column joins), but I was unable to find one that addressed this question.
This approach gave me the idea for the following (which yields a syntax error in MySQL).
SELECT tb1.*, tb2.x
FROM tableA tb1
INNER JOIN tableB tb2
ON tb1.* = tb2.*
Is there something similarly brief to the above syntax that can be used to define this join without writing each column name twice?
Why am I trying to doing this?
In case this seems incredibly inefficient, the basis for this join is that there are rows in the first table that I'm planning on deleting provided I can get an exact match to them based on all the columns in the second.
The column names are the same in each table.
You can try USING when joining the tables. Something like:
SELECT * FROM
A JOIN B
USING (column1,column2,column3, ... ,column50)
Note that the columns must have the same name in both tables.
Since the column names are the same in both tables you can use a Natural Join.
SELECT a.* FROM a NATURAL JOIN b;
Here is an example using SQL Fiddle
If there are not nullable columns then you can use this. Note that on phpMyAdmin shows an error but in MySQL console runs correct (it's a phpMyAdmin bug).
SET #sql = NULL;
SELECT GROUP_CONCAT(COLUMN_NAME) INTO #sql
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'table_1' AND table_schema = 'your_database_table_schema ';
SET #sql = CONCAT('SELECT table_1.* FROM table_1 JOIN table_2 USING (', #sql, ')');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
As I've attempted this myself, I'll go out on a limb and say "no", there's no syntax allowing you to simplify this comparison.
However, and assuming you don't have NULLable columns (per lad2025), there is at least one workaround:
Because you're matching a large number of columns, you could merge both tables into a temporary table that has at least those columns in common. If you create a primary key that includes all the columns for which you want to consider the rows identical, then your temporary table can only contain one of the rows.
So if you INSERT table A into the temporary table, then INSERT IGNORE table B into the temporary table, then the records of table B that DON'T appear in the temporary table are your matches.

Select distinct index names

I need to select all indexes from a given table.
But, it looks like MySQL creates multiple indexes with the same name with all the possible column combinations when there is more than one column in the index.
So SHOW INDEXES returns multiple times the same value.
Is there a way to do a select distinct to get the index names from a given table?
And if possible that is not MySQL specific.
Please try this query:
SELECT DISTINCT INDEX_NAME FROM information_schema.statistics
WHERE table_schema = 'your_schema'
AND table_name = 'your_table'

difference in DataBases

How to make query to information_schema.tables to get list of available tables which is exist in one DB but not exist in another one, something like diff but more suitable. I just need sql query.
So i have Db's like A,B,C,D and all these DB's should has the same tables, how I can check it ?
try
select *
from INFORMATION_SCHEMA.tables
group by table_name
having count(table_schema) < 4
if you have 4 DB's. If more you have to adjust the having clause.
This query give you all unique tables in all databases.
SELECT *,count(TABLE_NAME)
FROM
`TABLES` group by table_name
having count(TABLE_NAME)=1
And if you want repeated table names then use this
SELECT *,count(TABLE_NAME)
FROM
`TABLES` group by table_name
having count(TABLE_NAME)>1

What is the equivalent to Access' 'SELECT DISTINCTROW * FROM...' in SQLite?

I am converting a DB from Access to SQLite and therefore have to convert/debug all of the sql queries as well. Came across this one:
SELECT DISTINCTROW * FROM table WHERE column = value ORDER BY column2;
What is the equivalent query using SQLite?
SELECT DISTINCT * FROM table WHERE column = value ORDER BY column2;
Since there's only one table involved, DISTINCTROW acts like DISTINCT.
The equivalent is to ensure that all your tables have keys and that you implement joins and the rest of your query correctly. If you do that then you will never need anything like DISTINCTROW. DISTINCTROW is no more than just a legacy of silliness from Jet.
SELECT * is poor practice. List the columns by name.
SELECT column, column1, column2
FROM table
WHERE column = value
ORDER BY column2;