我遇到问题,我在数据库中有多行包含相同的电子邮件。重复的行是由于希望更新其信息的联系人而不是更新它将作为新行插入。
我想要做的是在给定电子邮件的情况下合并所有重复行,并将数据合并在一起作为PHP中返回的结果。
有一个特定的:
id
的行。例如,如果我有这些行:
id email prefix first_name
1 bob@bob.com Mr. Bob
2 bob@bob.com Bob
3 bob@bob.com Bobby
4 bob@bob.com Mr Bobby
5 bob@bob.com Bob
我希望合并的行成为:
email prefix first_name
bob@bob.com Mr Bob
由于前缀列不为空的id
最高的行为id = 4
,因此选择该行中的前缀值合并为最终结果。
同样地,联系人将他的名字从Bob改为Bobby,然后又改回Bob;因为最高id
行包含Bob
,即合并的值。
注意有更多列,这些只是一个简短的例子。
这是我的SQL语句:
$this->db->select('company, title, address_line1, address_line2, address_line3, city, state/prov, country, postal_code');
$this->db->from('visitor_contacts');
$this->db->where('email', $email);
如果有人能帮我完成这件事,我将不胜感激。如果在SQL中这是可能的,那将是非常棒的,但如果不是,也可以使用PHP解决方案。
答案 0 :(得分:0)
在MySQL中,一种方法使用group_concat()
:
select email
substring_index(group_concat(prefix order by (prefix is not null) desc, id desc separator '|'
), '|', 1) as prefix,
substring_index(group_concat(first_name order by (first_name is not null) desc, id desc separator '|'
), '|', 1) as first_name,
. . .
from t
group by email;
方法是将值连接在一起然后提取第一个元素。
一些注意事项:
group_concat()
的中间字符串有(可配置的)最大长度。您可能需要增加其大小。'|'
)不应出现在任何值中。另一种方法使用相关子查询:
select e.email,
(select t2.prefix
from t t2
where t2.email = t.email and t2.prefix is not null
order by id desc
limit 1
) as prefix,
(select t2.first_name
from t t2
where t2.email = t.email and t2.first_name is not null
order by id desc
limit 1
) as first_name,
. . .
from (select distinct email from t) e;
此方法具有保留原始类型的优点。