How to write generic code for union tables over years? - mysql

I have an Hive ETL job where I have to extract data from yearly tables and union them. Don't ask why there is a separate table for each year (legacy systems and huge size).
Lets assume table names are table11, table12, . . ., table19
Now I can write query upto 'from' table19, but I want to write generic code, otherwise the code have to be updated every year. I believe one can't use wildcards in the 'from' clause, if I am correct. e.g. table20*
Best Regards,

you can use prepared statement. So you can generate a query with CONCAT and then execute it.
-- SELECT CONCAT("insert into newtable select * from table",DATE_FORMAT(now(),'%y'))
SELECT CONCAT(" select * from mysql.user") INTO #sql;
SELECT #sql;
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

Related

Get specifi field value from a dynamic SQL in MYSQL

I am trying to create and execute sql dynamically in MYSQL. I have a field myColumn and i want to show/get the value of this field. The below script will get me all data in the table,
SET #value:='myColumn';
SET #sql:=CONCAT("SELECT * FROM change c where c.field='",#value"'");
PREPARE dynamic_statement FROM #sql;
EXECUTE dynamic_statement;
DEALLOCATE PREPARE dynamic_statement;
The reason i want to do this is because I want to work on that specific field. Like execute a function on the field for e.g. repalce,substring etc etc. I know i can do any work inside #sql but i want to know if i can access the columns once the sql is executed.
select #sql.myColumn will not work. How can i achieve this?

How do i access a database using the returned results of a table?

create table a.a {
db varchar(255)
}
//first record of a.a is db = b
create table b.a {
id varchar(255)
}
mysql to run:
use concat((select * from a.a limit 1),".a"); select * from a;
How can i achieve the above? Using the returned results of one table to access another database without doing round trips to mysql connection.
Dynamic SQL requires using PREPARE in a stored procedure.
SET #sql = (SELECT CONCAT('SELECT * FROM `', a.a, '`')
FROM a
LIMIT 1);
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
It's generally considered best to avoid designing your database so that it requires this. Don't spread the data among multiple tables with the same structure, use a single table and add another column to distinguish the records.

Use user-defined variable in Create Table statement to specify varchar length

I want to be able to do something like this:
SET #foo_width = 10;
CREATE TABLE test_table (
foo varchar(#foo_width)
);
The exact problem is that I will need the same varchar-width for different columns across different tables. So, thought it'd be better if it could be stored in a variable.
Is there any alternative?
You can't do it directly, and MySQL doesn't support user-defined types.
At best, you can use PREPARED STATEMENT like this or you generate your query in your application.
SET #foo_width = 10;
SELECT CONCAT("CREATE TABLE test_table (
foo varchar(",#foo_width,")
);") INTO #myquery;
select #myquery; -- only for test
PREPARE stmt FROM #myquery;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

Dynamic table name based on date

I have some tables which have dates in it.
How can I query on them based on the dates. There are multiple tables with prefix_date format.
I mean if the name of the table is foo and today's date being 2016 06 09. The table I need to access will be foo_2016_06_09.
I need to run this query daily on the day before date. Is this possible? If yes how?
DATE_FORMAT(NOW(),'%Y_%m_%d') will return as 2016_06_09, you can concatenate the remain table name part and use as dynamic query:
SET #table_name:='foo_';
SET #date_part:=DATE_FORMAT(NOW(),'%Y_%m_%d');
SET #sql:=CONCAT('SELECT * FROM ', #table_name, #date_part);
PREPARE dynamic_statement FROM #sql;
EXECUTE dynamic_statement;
DEALLOCATE PREPARE dynamic_statement;
For the previous day, use DATE_SUB
SET #date_part:=DATE_FORMAT(DATE_SUB(NOW(),INTERVAL 1 DAY),'%Y_%m_%d');

Using a variable in the FROM clause

I need to choose a table according to an instruction. But if I use a variable to store the name of the table, MySQL returns error 1064.
SET #eligetabla ='convenios';
select * from #eligetabla;
How can I use a variable for a table following the from clause?
Not that I think this is a particularly fantastic idea, and its quite the pain, but you can do this:
SET #eligetabla='convenios';
SET #sql=CONCAT("SELECT * FROM ", #eligetabla);
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
You may as well be choosing the table application side and building your query there, tho.