我遇到一个问题,数据库中有多行包含相同的电子邮件。重复的行是由于联系人希望更新其信息,而不是更新,而是将其作为新行插入。
我想要做的是合并给定电子邮件的所有重复行,并将数据合并在一起作为 PHP 返回的结果。
有一个具体的:
- 对于 x 行数,从给定列合并的值应该是具有最高
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
,因此选择该行中的 prefix 值合并到最终结果。
同样,联系人将他的名字从 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 解决方案。
最佳答案
在 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;
此方法的优点是保留原始类型。
关于php - 合并 MySQl 行作为结果,其中数据是最新的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38640210/