Search code examples
mysqlunionprocedure

Procedure UNION on tables


How can I UNION all results from stmtQuery to ONE RESULTS example results from table basia and Comments_11 .... etc

    DELIMITER $$
DROP PROCEDURE IF EXISTS SearchUserY $$
CREATE PROCEDURE `SearchUserY`(IN UserIdValue INT(11) )
BEGIN
       DECLARE done INT DEFAULT FALSE;
       DECLARE tableName VARCHAR(50);
       DECLARE stmtFields TEXT ; 
       DECLARE columnName VARCHAR(50) default 'UserId';

        DECLARE cursor1 CURSOR FOR
            SELECT table_name
            FROM information_schema.COLUMNS
            WHERE table_schema = 'comments' 
            AND column_name LIKE '%UserId';

        DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;


        OPEN cursor1;
        read_loop: LOOP
        FETCH cursor1 INTO tableName;
        IF done THEN
            LEAVE read_loop;
        END IF;

      SET stmtFields = CONCAT('`',tableName,'`','.' , columnName ,'=', UserIdValue) ;


     SET @stmtQuery=CONCAT(@sql,'SELECT Nick, Title, Content FROM ' ,'`',tableName,'`', ' WHERE ', stmtFields ) ;
   select @stmtQuery;


        END LOOP;

       PREPARE stmt FROM @stmtQuery ;
       EXECUTE stmt ;

       DEALLOCATE PREPARE stmt;
       CLOSE cursor1;
END

results example (select @stmtQuery):

     SELECT Nick, Title, Content FROM `basia` WHERE `basia`.UserId=0
     SELECT Nick, Title, Content FROM `Comments_11` WHERE `Comments_11`.UserId=0
     ... etc

I want get a one results from all this query but know I got only One results


Solution

  • Generate query in a loop using CONCAT function, add 'UNION' or 'UNION ALL' clause between them, then execute result query with a prepared statements.

    Solution without cursor:

    SET @resultQuery = NULL;
    SELECT
      GROUP_CONCAT(
        DISTINCT
        CONCAT('SELECT Nick, Title, Content FROM ', table_name, ' WHERE UserId = ', UserIdValue)
        SEPARATOR '\r\nUNION\r\n'
      )
    INTO
      @resultQuery
    FROM
      information_schema.COLUMNS
    WHERE
      table_schema = 'comments' AND column_name LIKE '%UserId';
    
    SELECT @resultQuery;
    

    It will produce result like this:

    SELECT Nick, Title, Content FROM table1 WHERE UserId = 10
    UNION
    SELECT Nick, Title, Content FROM table2 WHERE UserId = 10
    UNION
    SELECT Nick, Title, Content FROM table3 WHERE UserId = 10
    UNION
    SELECT Nick, Title, Content FROM table4 WHERE UserId = 10
    ...
    

    Increase group_concat_max_len variable if needed. It is the maximum allowed result length for the GROUP_CONCAT() function, default value = 1024.