使用行值连接多个表

时间:2016-07-22 16:57:20

标签: mysql join

我有3个表event1,event2,event2,它包含参与活动的所有用户。每个表都有近百万个数据。随着新事件的发展,这些表格不断增加。

我有一个客户表,其中包含该事件的所有客户

Event1
+------+------------+---------+
| id   | phone      | details |
+------+------------+---------+
|    1 | 1234567890 | Detail1 |
|    2 | 2345678901 | Detail2 |
|    3 | 3456789012 | Detail3 |
+------+------------+---------+

Event 2
+------+------------+---------+
| id   | phone      | details |
+------+------------+---------+
|    1 | 1234567890 | Detail1 |
|    2 | 2345678901 | Detail2 |
|    3 | 3456789012 | Detail3 |
+------+------------+---------+

Event 3
+------+------------+---------+
| id   | phone      | details |
+------+------------+---------+
|    1 | 1234567890 | Detail1 |
|    2 | 2345678901 | Detail2 |
|    3 | 3456789012 | Detail3 |
+------+------------+---------+

Customer
+------+------------+--------------+
| id   | phone      | event_name |
+------+------------+--------------+
|    1 | 1234567890 | event1       |
|    2 | 4567890123 | event2       |
|    3 | 7890123456 | event3       |
+------+------------+--------------+

要获取客户详细信息,我已遍历此查询中的3个表

SELECT cu.*,c.* FROM customer cu JOIN event1 c WHERE cu.phone=c.phone


SELECT cu.*,c.* FROM customer cu JOIN event2 c WHERE cu.phone=c.phone


SELECT cu.*,c.* FROM customer cu JOIN event3 c WHERE cu.phone=c.phone

http://sqlfiddle.com/#!9/1c8bf/2

如何在单个查询中执行此操作。我为每个客户保存了表名。

3 个答案:

答案 0 :(得分:1)

您可以加入多个表格

transition.ease([value[, arguments]])

编辑: 使用左连接而不是INNER JOIN,因为客户可以与事件1或事件2或事件3相关联,或者不一定与任何事件相关联。然后,左连接将为客户未与之关联的事件的值产生NULL,从而返回期望的结果。对于每个客户,他与之关联的列表事件并不一定与所有客户关联,以作为记录返回。

答案 1 :(得分:1)

这可以使用游标动态生成这些查询来实现。

DROP PROCEDURE IF EXISTS `SP_GetAll`//

CREATE PROCEDURE `SP_GetAll`
( 
)
BEGIN
declare done int;
DECLARE table_name      VARCHAR(255) ;  
DECLARE str      VARCHAR(255) ; 

DECLARE cursor_name CURSOR FOR 
select event_name from customer;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
SET  str:='';
SET done = 0 ;
   OPEN cursor_name;
read_loop: LOOP
FETCH cursor_name INTO table_name;

IF done=1 THEN
        LEAVE read_loop;
    END IF;
 SET str=CONCAT(str, 'SELECT cu.*,c.* FROM customer cu JOIN ', 
                table_name ,' c on cu.phone=c.phone;');


  END LOOP;
  select str; //this can be changed to direct execution if needed
  CLOSE cursor_name;
END//

执行此sp CALL SP_GetAll();结果动态查询如下..

SELECT cu.*,c.* FROM customer cu JOIN event1 c on cu.phone=c.phone;SELECT cu.*,c.* FROM customer cu JOIN event2 c on cu.phone=c.phone;SELECT cu.*,c.* FROM customer cu JOIN event3 c on cu.phone=c.phone;

答案 2 :(得分:0)

SELECT cu.*,c.* FROM customer cu JOIN event1 c WHERE cu.phone=c.phone
UNION
SELECT cu.*,c.* FROM customer cu JOIN event2 c WHERE cu.phone=c.phone
UNION
SELECT cu.*,c.* FROM customer cu JOIN event3 c WHERE cu.phone=c.phone

您可以使用UNION

组合多个查询的搜索结果

Fiddle

Adjusted the answer of Prashant:

正如Prashan所示,您可以使用动态SQL来构建和连接查询字符串。如果你然后更换&#34 ;;"在"结果字符串中UNION"并直接执行您将获得结果集的字符串(此外,您必须使用会话变量才能执行查询字符串)。 Fiddle

CREATE PROCEDURE `SP_GetAll`()
BEGIN
declare done int;
DECLARE table_name VARCHAR(255) ;  
DECLARE str VARCHAR(1000) ; -- attention: value must be high enough to contain the whole query, so you have to estimate the string length

DECLARE cursor_name CURSOR FOR 
select event_name from customer;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
SET @str='';
SET done = 0 ;
   OPEN cursor_name;
read_loop: LOOP
FETCH cursor_name INTO table_name;

IF done=1 THEN
        LEAVE read_loop;
    END IF;
 SET @str=CONCAT(@str, ';SELECT cu.*,c.* FROM customer cu JOIN ', table_name ,' c on cu.phone=c.phone');

  END LOOP;

  SET @str = SUBSTRING(@str, 2);
  SET @str = REPLACE(@str, ";", " UNION ");

  PREPARE QUERY FROM @str;
  EXECUTE QUERY;
  CLOSE cursor_name;
END//