用选择填充值

时间:2018-10-08 08:13:00

标签: mysql database join left-join

更新:这是该问题的演示:http://www.sqlfiddle.com/#!9/15ff5e/1

我正在尝试对以下2个表执行左连接:

post_metrics

| post_id | likes |
|---------|-------|
| 'aaa'   |     3 |
| 'aaa'   |     7 |
| 'aaa'   |     8 |
| 'bbb'   |     2 |
| 'bbb'   |     4 |

post_history

| post_id | post_text |
|---------|-----------|
| 'aaa'   | 'doug'    |
| 'bbb'   | 'steve'   |

结果类似于以下内容:

| post_id | likes | post_text |
|---------|-------|-----------|
| 'aaa'   |     3 | 'doug'    |
| 'aaa'   |     7 | NULL      |
| 'aaa'   |     8 | NULL      |
| 'bbb'   |     2 | 'steve'   |
| 'bbb'   |     4 | NULL      |

我想用前几行的数据填充这些NULL值,这样结果是这样的:

| post_id | likes | post_text |
|---------|-------|-----------|
| 'aaa'   |     3 | 'doug'    |
| 'aaa'   |     7 | 'doug'    |
| 'aaa'   |     8 | 'doug'    |
| 'bbb'   |     2 | 'steve'   |
| 'bbb'   |     4 | 'steve'   |

但是,我正在使用的查询...

SELECT m.id,
       m.likes,
       @username := ifnull(p.username, @username) as username
FROM (select * from `post_metrics` WHERE post_id = @post_id) AS m
LEFT JOIN `post_history` AS p ON (m.post_id = p.post_id)

...给我以下结果:

| post_id | likes | post_text |
|---------|-------|-----------|
| 'aaa'   |     3 | 'doug'    |
| 'aaa'   |     7 | 'steve'   |
| 'aaa'   |     8 | 'steve'   |
| 'bbb'   |     2 | 'steve'   |
| 'bbb'   |     4 | 'steve'   |

如何正确填充前几行的空值?

这些是具有数百万行和约6列的稀疏空值要填充的表。每个post_id的“ post_text”字段并不总是相同的(偶尔会变化),因此我需要将这些更改传播到以下具有NULL的行中。

2 个答案:

答案 0 :(得分:1)

尝试使用内部联接

SELECT m.id,
       m.likes,
       m.username 
       from `post_metrics`  m
inner JOIN `post_history` AS p ON m.post_id = p.post_id

答案 1 :(得分:1)

现有查询的问题是@username是根据查询的无序行输出计算的。因此,您需要先对数据进行排序,然后进行username替换(或根据您的SQLFiddle,post_text)。因此,我认为此查询应该可以满足您的要求:

SELECT post_id, 
       date, 
       likes,
       @post_text := COALESCE(post_text, @post_text) AS post_text
FROM (SELECT 
       m.post_id,
       m.date,
       m.likes,
       p.post_text 
      FROM `post_metrics` m
      LEFT JOIN `post_history` AS p ON m.post_id = p.post_id and m.date = p.date
      ORDER BY m.post_id, m.date) o
JOIN (SELECT @post_text := '') t

输出:

post_id     date        likes   post_text
aaa         2018-09-01  3       ccccc
aaa         2018-09-02  7       ccccc
aaa         2018-09-03  8       ccccd
bbb         2018-09-01  2       eeeee
bbb         2018-09-02  4       eeeee

SQLFiddle Demo