在 MySql 上查询并加入多列

Query And Join Multiple Column on MySql

我有两个 table 在我们的 MySQL 数据库中有大数据。

tbl_phonebook :

 PB_ID    CUST_NAME     PHONE1     PHONE2      PHONE3     PHONE4
 1        Richard       11111      12222       13333      14444
 2        Maria         21111      22222       23333      24444
 3        Robert        31111      32222       33333      34444
 

tbl_calllog :

 LOG_ID   CALL_TIME     PHONENUMBER   
 1        2020-06-01    22222       
 2        2020-06-01    55555
 3        2020-06-01    13333

如何以最佳性能获得这样的结果:

 LOG_ID   CALL_TIME     PHONENUMBER   CUST_NAME
 1        2020-06-01    22222         Maria
 2        2020-06-01    55555         -
 3        2020-06-01    13333         Richard

谢谢。

您只想将 Cust_Name 附加到您的调用 table...所以左连接到调用 table 就足够了:

SELECT tcl.*,
       tpb.Cust_Name
FROM tbl_calllog tcl
LEFT JOIN tbl_phonebook tpb ON (tcl.phonenumber = tpb.phone1
                                OR tcl.phonenumber = tpb.phone2
                                OR tcl.phonenumber = tpb.phone3
                                OR tcl.phonenumber = tpb.phone4)

注意: 如果 tbl_phonebook 中的 phone 数字不是唯一的,您将需要查看替代联接。

请试试这个查询:

select 
  c.LOG_ID, c.CALL_TIME, c.PHONENUMBER, p.CUST_NAME 
from 
  tbl_calllog c 
left join 
  tbl_phonebook p 
on 
  c.PHONENUMBER in (p.PHONE1, p.PHONE2, p.PHONE3, p.PHONE4);

我担心当前查询不是最佳性能,因为 mysql 必须检查所有 phone 列中的条件。

设置一个新的 table 以将 phone 号码映射到用户,如下所示:

create table tbl_phonebook (
  `PB_ID` int(11) NOT NULL,
  `CUST_NAME` varchar(11) DEFAULT NULL,
  `PHONE` int(11) DEFAULT NULL,
  PRIMARY KEY (`PB_ID`),
  index idx_p1 (PHONE)
) ENGINE=InnoDB;
insert into tbl_phonebook2 (CUST_NAME, PHONE)
VALUES ('Richard', 11111),
       ('Richard', 12222),
       ('Richard', 13333),
       ('Richard', 14444),
       ('Maria', 21111),
       ('Maria', 22222),
       ('Maria', 23333),
       ('Maria', 24444),
       ('Robert', 31111),
       ('Robert', 32222),
       ('Robert', 33333),
       ('Robert', 34444);

查询将是:

select
       c.LOG_ID, c.CALL_TIME, c.PHONENUMBER, p.CUST_NAME
from
     tbl_calllog c
left join
    tbl_phonebook2 p
on c.PHONENUMBER = p.PHONE;

结果及执行计划如下:

mysql> select
    ->        c.LOG_ID, c.CALL_TIME, c.PHONENUMBER, p.CUST_NAME
    -> from
    ->      tbl_calllog c
    -> left join
    ->     tbl_phonebook2 p
    -> on c.PHONENUMBER = p.PHONE;
+--------+------------+-------------+-----------+
| LOG_ID | CALL_TIME  | PHONENUMBER | CUST_NAME |
+--------+------------+-------------+-----------+
|      1 | 2020-06-01 |       22222 | Maria     |
|      2 | 2020-06-01 |       55555 | NULL      |
|      3 | 2020-06-01 |       13333 | Richard   |
+--------+------------+-------------+-----------+
3 rows in set (0.00 sec)

mysql> explain select
    ->        c.LOG_ID, c.CALL_TIME, c.PHONENUMBER, p.CUST_NAME
    -> from
    ->      tbl_calllog c
    -> left join
    ->     tbl_phonebook2 p
    -> on c.PHONENUMBER = p.PHONE;
+----+-------------+-------+------------+------+---------------+--------+---------+--------------------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key    | key_len | ref                | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+--------+---------+--------------------+------+----------+-------+
|  1 | SIMPLE      | c     | NULL       | ALL  | NULL          | NULL   | NULL    | NULL               |    3 |   100.00 | NULL  |
|  1 | SIMPLE      | p     | NULL       | ref  | idx_p1        | idx_p1 | 5       | test.c.PHONENUMBER |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+--------+---------+--------------------+------+----------+-------+
2 rows in set, 1 warning (0.00 sec)