简体   繁体   English

Mysql 根据日期将多行数据放到一行

[英]Mysql place data on multiple rows into one row based on date

I have the following data in a MYSQL table.我在 MYSQL 表中有以下数据。

ID ID NAME姓名 PHONENO电话号码 EMAIL EMAIL TMDate TMD日期
1234 1234 Sarah莎拉 0884100300 0884100300 1-Jan-21 21 年 1 月 1 日
1234 1234 Sarah莎拉 0881500900 0881500900 5-Mar-21 21 年 3 月 5 日
1234 1234 Sarah莎拉 Sarah@gmail.com Sarah@gmail.com 10-Mar-21 21 年 3 月 10 日
0001 0001 James詹姆士 09991234567 09991234567 31-Dec-20 20 年 12 月 31 日
0001 0001 James詹姆士 james@yahoo.com james@yahoo.com 31-Dec-20 20 年 12 月 31 日

The table contain email and phone numbers for customers.该表包含客户的 email 和电话号码。 If the phonenumber or email is updated, the data is recorded on a new row.如果电话号码或 email 更新,则数据将记录在新行上。 The TMDate column shows when the record was collected. TMDate 列显示收集记录的时间。

I want the final output to be as follows:我希望最终的 output 如下:

ID ID NAME姓名 PHONENO电话号码 EMAIL EMAIL
1234 1234 Sarah莎拉 0881500900 0881500900 example@gmail.com示例@gmail.com
0001 0001 James詹姆士 09991234567 09991234567 james@yahoo.com james@yahoo.com

My approach was to first pull the phone numbers based on max data using script below and then pull the emails using a script with similar logic and then do inner join of the two我的方法是首先使用下面的脚本根据最大数据提取电话号码,然后使用具有类似逻辑的脚本提取电子邮件,然后对两者进行内部连接

 SELECT t1.id,
   t1.name
   t2.PHONENO,
   t2.max_date
 FROM phoneemail t1
  INNER JOIN
   (SELECT id,PHONENO, MAX(TMDATE) as max_date FROM phoneemail group by id,phoneno where t1.phoneno 
 is not null) t2
   ON t1.id = t2.id

My approach is not working as I am still getting duplicate records我的方法不起作用,因为我仍然收到重复记录

MySQL does not have a "first" or "last" aggregation function. MySQL 没有“第一个”或“最后一个”聚合 function。 So, one method is to use window functions:因此,一种方法是使用 window 函数:

select distinct id, name,
       first_value(phone ignore nulls) over (partition by id order by tmdate desc) as phone,
       first_value(email ignore nulls) over (partition by id order by tmdate desc) as email
from (select distinct id, name from t) t;

Happily, first_value() has the ignore nulls option.令人高兴的是, first_value()具有ignore nulls选项。

The columns PHONENO and EMAIL my have been updated in different dates, so getting the latest date for each ID will not help. PHONENOEMAIL列已在不同日期更新,因此获取每个 ID 的最新日期将无济于事。

If your version of MySql is 8.0+ you can do it with FIRST_VALUE() window function, which does not support IGNORE NULLS , so conditional sorting is also needed:如果您的 MySql 版本是 8.0+,您可以使用FIRST_VALUE() window function 来实现,它不支持IGNORE NULLS条件排序,所以还需要条件 NULLS,

SELECT DISTINCT ID, NAME,
       FIRST_VALUE(PHONENO) OVER (PARTITION BY ID, NAME ORDER BY PHONENO IS NULL, TMDate DESC) PHONENO,
       FIRST_VALUE(EMAIL) OVER (PARTITION BY ID, NAME ORDER BY EMAIL IS NULL, TMDate DESC) EMAIL
FROM phoneemail 

For prior versions you need 2 correlated subqueries:对于以前的版本,您需要 2 个相关的子查询:

SELECT DISTINCT p1.ID, p1.NAME,
  (SELECT p2.PHONENO FROM phoneemail p2 
   WHERE (p2.ID, p2.NAME) = (p1.ID, p1.NAME) AND p2.PHONENO IS NOT NULL 
   ORDER BY TMDate DESC LIMIT 1) PHONENO,
  (SELECT p3.EMAIL FROM phoneemail p3 
   WHERE (p3.ID, p3.NAME) = (p1.ID, p1.NAME) AND p3.EMAIL IS NOT NULL 
   ORDER BY TMDate DESC LIMIT 1) EMAIL 
FROM phoneemail p1

See the demo .请参阅演示
Results:结果:

ID ID NAME姓名 PHONENO电话号码 EMAIL EMAIL
1234 1234 Sarah莎拉 0881500900 0881500900 Sarah@gmail.com Sarah@gmail.com
0001 0001 James詹姆士 09991234567 09991234567 james@yahoo.com james@yahoo.com

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM