假设我有一个这样的表:选择在MySQL从以前的行多列
| id | date | name | value |
|----|------------|------|-------|
| 0 | 2017-01-14 | foo | one |
| 1 | 2017-01-17 | bar | two |
| 2 | 2017-01-18 | john | five |
| 3 | 2017-01-19 | doe | ten |
(其中date
不一定要订购)
我希望能够选择的一些值以前的行(根据date
)。这样的功能可以通过下面的查询来实现:
SELECT
*,
(SELECT
name
FROM
example e2
WHERE
e2.dt < e1.dt
ORDER BY dt DESC
LIMIT 1
) as prev_name
FROM example e1
,导致表:
| id | dt | name | value | prev_name |
|----|------------|------|-------|-----------|
| 0 | 2017-01-14 | foo | one | (null) |
| 1 | 2017-01-17 | bar | two | foo |
| 2 | 2017-01-18 | john | five | bar |
| 3 | 2017-01-19 | doe | ten | john |
现在,这工作得很好。然而,这将是可取的,如果我能很容易地从上一行选择多列,造成像结果:
| id | dt | name | value | prev_name | prev_value | prev_dt |
|----|------------|------|-------|-----------|------------|------------|
| 0 | 2017-01-14 | foo | one | (null) | (null) | (null) |
| 1 | 2017-01-17 | bar | two | foo | one | 2017-01-14 |
| 2 | 2017-01-18 | john | five | bar | two | 2017-01-17 |
| 3 | 2017-01-19 | doe | ten | john | five | 2017-01-18 |
当然这是可以实现通过简单的复制子查询(SELECT [..] FROM example e2 ...)
到查询多次,但我想这不是最好的选择。我发现了几个关于SO寻址的问题或者“如何从前一行中选择记录”或“如何使用子查询选择多列”问题,但不是两者都有。后面的问题主要通过使用JOIN
声明来解决,但我认为这不能与“上一行”情况组合。所以我的问题是:什么是产生最后结果的更好方法,而不是为我们需要的每个列复制一个子查询?
编辑。作为一个额外的约束,我没有在原始问题中包含,“previous”实际上可能与前一行有所不同,而是“满足条件的前一行”。因此,假设我的表中包含一个额外boolean
列b
| id | dt | name | value | b |
|----|------------|------|-------|---|
| 0 | 2017-01-14 | foo | one | 1 |
| 1 | 2017-01-17 | bar | two | 0 |
| 2 | 2017-01-18 | john | five | 1 |
| 3 | 2017-01-19 | doe | ten | 0 |
我想“前行”是上一行与b = 1
,所以期望的结果将是:
| id | dt | name | value | b | prev_name | prev_value | prev_dt |
|----|------------|------|-------|---|-----------|------------|------------|
| 0 | 2017-01-14 | foo | one | 1 | (null) | (null) | (null) |
| 1 | 2017-01-17 | bar | two | 0 | foo | one | 2017-01-14 |
| 2 | 2017-01-18 | john | five | 1 | foo | one | 2017-01-14 |
| 3 | 2017-01-19 | doe | ten | 0 | john | five | 2017-01-18 |
我觉得这仍然可以通过James Scott的回答完成,只需更新b = 1
时使用IF
-statement的变量,但在这种情况下可能有另一种解决方案。
编辑。SQLfiddle
为防万一你已经阅读我的答案,我犯了一个错误,现在已经纠正了这个问题 –
你想实现什么?请评论你的问题陈述。 – Imran
我想要选择所有的行,例如前一行的值为'x',名称'y'等。这可以通过在SELECT * FROM([query])中嵌入我要查询的查询作为temp WHERE prev_name = [...]和prev_value = [..]'。此外,我的原始问题还没有完全完成,我在编辑中添加了一些额外的信息。 – konewka