【问题标题】:fill values with select用选择填充值
【发布时间】:2018-10-08 08:12:59
【问题描述】:

更新:这是问题的演示: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 的行。

【问题讨论】:

  • 为什么直接LEFT JOIN 不起作用? sqlfiddle.com/#!9/624cb/5
  • @Nick 这是一个展示问题的更新示例:sqlfiddle.com/#!9/15ff5e/1 原始问题中没有包含一些附加参数,试图找到显示问题的最小示例,我想我现在有了,很抱歉造成混乱

标签: mysql database join left-join


【解决方案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

【讨论】:

  • 这似乎确实解决了我遇到的问题谢谢???
  • 你能解释一下最后一个连接的确切作用吗?
  • @Milo 最后的连接只是为了初始化变量@post_text 的值。取决于您的 MySQL 服务器,不初始化它可能会在以后尝试在 COALESCE 表达式中使用它时导致问题。它用作将SET @post_text := ''; 语句放在SELECT 之前的快捷方式
【解决方案2】:

使用内连接试试下面

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

【讨论】:

  • 我已经更新了问题,这个解决方案将不起作用,因为两个源表的列不通用
  • 修改了答案-你现在可以查看
  • 感谢您到目前为止的时间,我已经制作了一个最小示例来展示我遇到的问题:sqlfiddle.com/#!9/15ff5e/1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-24
  • 1970-01-01
  • 2013-05-07
  • 1970-01-01
  • 2018-03-01
  • 1970-01-01
相关资源
最近更新 更多