合并MySQl行作为结果,其中数据是最新的

时间:2016-07-28 15:06:57

标签: php mysql sql codeigniter merge

我遇到问题,我在数据库中有多行包含相同的电子邮件。重复的行是由于希望更新其信息的联系人而不是更新它将作为新行插入。

我想要做的是在给定电子邮件的情况下合并所有重复行,并将数据合并在一起作为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,因此选择该行中的前缀值合并为最终结果。

同样地,联系人将他的名字从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解决方案。

1 个答案:

答案 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;

此方法具有保留原始类型的优点。