MySQL使用LIKE匹配基于另一个表填充字段

时间:2016-06-30 05:00:20

标签: php mysql

我知道它不是迄今为止最干净的代码,但我无法弄清楚为什么我无法使用这个代码。

我希望使用字段c.ClientNumber中的客户编号填充字段m.customersTemp。但只有当找到来自c.EmailAddress的LIKE匹配时才会发现m.Emails ... m.Emails是一个包含电子邮件列表的字段。代码如下。

UPDATE market m, customer c
SET m.customersTemp = CONCAT(m.customersTemp, c.ClientNumber)
WHERE m.Emails LIKE CONCAT('%', TRIM(c.EMailAddress), '%')
AND TRIM(c.EMailAddress)<>''

字段m.customersTemp中的结果只显示一个值(客户编号)......我知道有很多匹配。

TABLE CUSTOMER
ClientNumber    | EMailAddress
1234              a@a.com
4567              b@b.com
2222              
1111              d@d.com

------------------------------------------------------------- 
|                        TABLE MARKET                       |
-------------------------------------------------------------
| ID            | Emails                     | customersTemp|
-------------------------------------------------------------
|1              | a@a.com, b@b.com, c@c.com  |              |
|2              | a@a.com, b@b.com, g@g.com  |              |
|3              | e@e.com                    |              |
|4              | f@f.com                    |              |
-------------------------------------------------------------

ID为1和2的customersTemp结果只有1个ClientNumber。 4567

1 个答案:

答案 0 :(得分:0)

请不要忘记阅读底部的警告,了解为什么不应该像这样保存您的数据。

您可以在备份副本上对此进行测试。我不会对你的主表运行它。类似于有人说:“在这里,试试这个删除命令,我认为它会起作用。”

-- drop table customer;
create table customer
(   ClientNumber int,
    EMailAddress varchar(100)
);
insert customer (ClientNumber,EMailAddress) values
(1234,'john@john.com'),
(4567,'joe@joe.com'),
(2222,''), 
(1111,'somone@someone.com'),
(5454,'john@john.com');

-- drop table market;
create table market
(   Emails varchar(100),
    customersTemp varchar(100)
);
insert market(Emails,customersTemp) values
('john@john.com',''),
('joe@joe.com',''),
('test@test.com',''),
('more@more.com','');

更新声明:

UPDATE market
INNER JOIN 
(   SELECT c.EMailAddress as e,GROUP_CONCAT(c.ClientNumber ORDER BY c.ClientNumber) theList
    FROM customer c
    GROUP BY c.EMailAddress
) xDerived1
ON market.EMails = xDerived1.e
SET market.customersTemp = xDerived1.theList;

<强>结果:

select * from market;
+---------------+---------------+
| Emails        | customersTemp |
+---------------+---------------+
| john@john.com | 1234,5454     |
| joe@joe.com   | 4567          |
| test@test.com |               |
| more@more.com |               |
+---------------+---------------+

版本2

drop table customer;
create table customer
(   ClientNumber int,
    EMailAddress varchar(100)
);
insert customer (ClientNumber,EMailAddress) values
(1234,'a@a.com'),
(4567,'b@b.com'),
(2222,''), 
(1111,'d@d.com'),
(8484,'g@g.com');
-- select * from customer;

drop table market;
create table market
(   id int auto_increment primary key,
    Emails varchar(100),
    customersTemp varchar(3000)
);
insert market(Emails,customersTemp) values
('a@a.com,b@b.com,c@c.com',''),
('a@a.com,b@b.com,g@g.com',''),
('e@e.com',''),
('f@f.com','');
-- select * from market;

drop table if exists marketHelper7;
create table marketHelper7
(   -- btw this might be the kind of table
    -- as an intersect/junction table that you
    -- should have to begin with
    -- and not have your CSV stuff 
    cid int not null,
    mid int not null
);

insert marketHelper7 (cid,mid)
select c.ClientNumber,m.id as MarketId
from customer c
join market m
on find_in_set(c.EMailAddress,m.Emails)>0;

update market set customersTemp=''; -- do a reset

UPDATE market m
join 
(   SELECT mh.mid as i,GROUP_CONCAT(mh.cid ORDER BY mh.cid) theList
    FROM marketHelper7 mh
    GROUP BY mh.mid
) xDerived1
ON m.id = xDerived1.i
SET m.customersTemp = xDerived1.theList;

drop table marketHelper7;

select * from market;
+----+-------------------------+----------------+
| id | Emails                  | customersTemp  |
+----+-------------------------+----------------+
|  1 | a@a.com,b@b.com,c@c.com | 1234,4567      |
|  2 | a@a.com,b@b.com,g@g.com | 1234,4567,8484 |
|  3 | e@e.com                 |                |
|  4 | f@f.com                 |                |
+----+-------------------------+----------------+

上面的版本2有助手表。

警告: 顺便说一句,永远不要保存这样的数据。这是疯了,表现很糟糕。请在Junction Tables(多对多)上查看我的答案(类似于关联表或“item has”表a.k.a.One-to-Many)。它们都是在查询期间使用数据规范化最佳实践和快速索引的相同概念。另外,如果不经常使用数据,或者想知道是否使用group_concat来破坏缓冲区大小,那么你会更开心。

请注意group_concat()具有灵活性,可以选择分隔符,并在函数调用中添加顺序。

group_concat输出的最大长度取决于系统变量group_concat_max_len,该变量可能默认为1K,但可以设置为至少4GB。

group_concat()上的Percona article以及group_concat()find_in_set()的手册页。