简体   繁体   中英

MySQL use a wild card in table name

So I have a software that store data on those tables. I know how those tables start but there will be always a suffix to them that's a number which I have no idea to know example of those table name is "itemid5_4423"

I know there is a table with the name itemid5 but i have no way to know the suffix number is there a wild card something similar to this logic select * from itemid5_*;

Let's say you have 2 tables like this:

create table itemid5_1111 (id int, itemname varchar(100));
create table itemid5_2222 (id int, itemname varchar(100));

You insert data into them:

insert into itemid5_1111 values (1, 'first table');
insert into itemid5_2222 values (2, 'second table');

Your goal is to get output like this from all itemid5* tables.

+------+--------------+
| id   | itemname     |
+------+--------------+
|    1 | first table  |
|    2 | second table |
+------+--------------+

You can do that by typing:

          select * from itemid5_1111
union all select * from itemid5_2222;

But, that's a lot of manual typing. You can make a stored procedure to dynamically query table names starting with itemid5 and then create a SQL dynamically and execute it.

Stored procedure

delimiter $$

drop procedure if exists get_items$$

create procedure get_items()
begin

    declare eof boolean default false;
    declare mytable varchar(255);
    declare first_run boolean default true;

    declare tablenames_cursor cursor for
        select table_name from information_schema.tables
        where table_name like 'itemid%';

    declare continue handler for not found
        set eof = true;

    set @my_query = '';

    open tablenames_cursor;
    read_loop: loop

        fetch tablenames_cursor into mytable;
        if eof then
            leave read_loop;
        end if;

        if first_run then
            set @my_query = concat('select * from ', mytable);
            set first_run = false;
        else
            set @my_query = concat(@my_query, ' union all ', 'select * from ', mytable);
        end if;

    end loop;
    close tablenames_cursor;

    prepare stmt from @my_query;
    execute stmt;
    deallocate prepare stmt;

end$$

delimiter ;

You call this procedure like so to get your results:

call get_items();

If you created a 3rd table like so:

create table itemid5_3333 (id int, itemname varchar(100));
insert into itemid5_3333 values (3, 'third table');

And then, you called the proc, you'd get

call get_items();
+------+--------------+
| id   | itemname     |
+------+--------------+
|    1 | first table  |
|    2 | second table |
|    3 | third table  |
+------+--------------+

i think using the data dictionary to retrieve the result would help, run this.

select * from information_schema.tables where table_name like 'itemid5_% ';

you can choose the columns you want that this query outputs, table_name is one of them you need, like we used it in where clause.

SELECT
REPLACE
    (
        GROUP_CONCAT(
            CONCAT("SELECT * FROM ", `TABLE_NAME`)
        ),
        ",",
        " UNION ALL "
    )
INTO @sq
FROM
    information_schema.tables
WHERE
    `TABLE_SCHEMA` = "test";
USE
    test;
PREPARE
    stmt1
FROM
    @sq;
EXECUTE
    stmt1;
DELIMITER //
CREATE PROCEDURE merge_tables(IN in_sname VARCHAR(64),IN in_tname VARCHAR(64))
READS SQL DATA
BEGIN
  DECLARE sname VARCHAR(64);   
  DECLARE tname VARCHAR(64);
  DECLARE cname VARCHAR(64);   
  DECLARE done INT DEFAULT FALSE; 
  DECLARE table_cur CURSOR FOR SELECT table_schema, table_name FROM 
    information_schema.TABLES WHERE table_schema = in_sname AND table_name LIKE 
    'table%';
  DECLARE column_cur CURSOR FOR SELECT `COLUMN_NAME` FROM 
    `INFORMATION_SCHEMA`.`COLUMNS` where table_schema = in_sname and table_name 
    = in_tname;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  -- build column list (Using the column list for table listed in second 
     parameter in PROC Call)
  SET @column = '';  
  OPEN column_cur;
  column_cur_loop: LOOP          
    FETCH column_cur INTO cname; 
    IF done THEN
      -- SET @column := CONCAT(@column, ') ');
       LEAVE column_cur_loop;
    END IF;
    IF @column = '' THEN    
      SET @column := CONCAT(@column,cname);
    ELSE
      SET @column := CONCAT(@column,',',cname);
    END IF;
  END LOOP;
  CLOSE column_cur;


  -- Build UNION Query for all table starting with table%)
  SET done = FALSE;
  SET @sql = '';  
  OPEN table_cur;
    table_list_loop: LOOP                 
        FETCH table_cur INTO sname, tname; 
        IF done THEN
          LEAVE table_list_loop;
        END IF;

        IF @sql = '' THEN    
          SET @sql := CONCAT('INSERT INTO MERGED_TABLE (', @column , ') SELECT 
          ', @column , ' FROM `', sname, '`.`', tname, '`');
        ELSE
          SET @sql := CONCAT(@sql, ' UNION ALL SELECT ' , @column , ' FROM `', 
          sname, '`.`', tname, '`');
        END IF;
      END LOOP;
      CLOSE table_cur;


  PREPARE stmt FROM @sql;  -- prepare and execute the dynamically
  EXECUTE stmt;            -- created query.
  DEALLOCATE PREPARE stmt;  

END //

DELIMITER ;`    

call merge_tables(testdb,table1)


**** testdb is Schema Name where tables reside **** table1 is one of the tables which needs to be merged to get column names **** table% in the procedure is the prefix of the all the tables that needs to be merged.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM