【问题标题】:Populate empty database columns with !empty older row columns用 !empty 旧行列填充空数据库列
【发布时间】:2015-11-27 06:00:18
【问题描述】:

假设我有一个包含以下行的数据库:

id (auto_incremented) | id_person | first_name | last_name | phone          | email
-----------------------------------------------------------------------------
1                     | 12        | kevin      | smith     |                | kevin@hotmail.com
2                     | 12        | kevin      | smith     | 1-800-123-4567 | 
3                     | 33        | joe        | jones     | 1-800-765-4321 | 
4                     | 33        | joe        | thompson  |                | joe@hotmail.com
5                     | 33        | joe        | thompson  |                | newjoe@hotmail.com

基于id_person,我想在单个查询中输出以下内容:

id | id_person | first_name | last_name | phone          | email
-----------------------------------------------------------------------------
2  | 12        | kevin      | smith     | 1-800-123-4567 | kevin@hotmail.com
5  | 33        | joe        | thompson  | 1-800-765-4321 | newjoe@hotmail.com

所以基本上,我只想获取最新的行值,如果它们为空,则从第一行不为空的行中获取值。

我该怎么做?希望这是有道理的。

【问题讨论】:

  • 清理数据比采用一些奇怪的数据检索方案要好。你能告诉我们为什么数据必须是这样的吗?
  • 好吧,我有 2 张桌子。一个用于people,另一个用于people_historypeople_history 表每人可以包含多于一行。我试图避免在两个表中使用完全相同的列,但这可能是我最好的选择...
  • 那么最好将两个表分开,当你想要最新的数据时使用peoplepeople_history表有重复数据是有原因的,就是存储一个人的历史数据。
  • @Populus 所说的,此外,您甚至可以通过在“当前数据”表上使用触发器来使历史记录表在某种程度上是自动的。
  • @daygloink : first_name 或 last_name 可以有空值吗?

标签: mysql select merge rows


【解决方案1】:
SELECT id_person, subQ.lastID
    , GROUP_CONCAT(IF(subQ.lastFieldXId = tblFields.ID, tblFields.fieldX, NULL)) AS fieldX
    , GROUP_CONCAT(IF(subQ.lastFieldYId = tblFields.ID, tblFields.fieldY, NULL)) AS fieldY
    [, ...]
FROM
(SELECT id_person
   , MAX(id) AS lastID
   , MAX(IF(IFNULL(fieldX, '') = '', 0, id) AS lastFieldXId
   , MAX(IF(IFNULL(fieldY, '') = '', 0, id) AS lastFieldYId
[, ....]
FROM theTable
GROUP BY id_person) AS subQ
LEFT JOIN theTable AS tblFields USING (id_person)
;

LEFT JOIN 可能会也可能不会更快

LEFT JOIN theTable AS tblFields 
ON tblFields.ID IN (subQ.lastFieldXId, subQ.lastFieldYId [, ...])

可能还有一种使用会话变量的方法,但我没有精力......

【讨论】:

    【解决方案2】:
    select * from(
    select p1.id,p1.id_person,p1.first_name,p1.last_name,
    ifnull(p1.phone,p2ph.phone) phone ,ifnull(p1.email,p3em.email) email
    
    from person p1
    left join person p2ph on(p1.id_person=p2ph.id_person and p2ph.phone is not null)
    left join person p3em on(p1.id_person=p3em.id_person and p3em.email is not null)
    order by id_person,p1.id desc,p2ph.id desc,p3em.id desc 
      )t group by id_person;
    

    http://sqlfiddle.com/#!9/d2f44/6验证

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-09
      • 1970-01-01
      • 2016-07-23
      • 1970-01-01
      • 2013-06-07
      • 1970-01-01
      • 2023-03-11
      相关资源
      最近更新 更多