SQL Return 1,0 in new variable based on case when statement referenced multiple other variables
SQL Return 1,0 in new variable based on case when statement referring to multiple other variables
我正在尝试创建一个新变量,该变量根据一系列日期和阶梯级别 (null-E) 在 MySQL 中填充 1(真)、0(假)。
参见fiddle:http://sqlfiddle.com/#!9/9975e1
其中 record_dates 和 ladder_levels 不一定按顺序排列。我想 return ladder_change 字段通过一个 case when (?) 语句,类似于:
- 首先,仅在匹配的 ID 中查找(即仅查找 ID 324)
- 然后,类似于:
case when record_date2 > record_date1 AND (ladder_level2 < ladder_level1 OR ladder_level2>ladder_level1) then 1, else 0
关于如何实现这一目标的任何提示?
- 由于没有定义主键,我假设数据是在
creation_date
和 ladder_level
上按顺序输入的。 记住数据以无序方式存储在MySQL。
- 首先,我们必须使用子select 查询来按要求的顺序获取数据(如上一步中突出显示的那样)。值得注意的是,
Order By
是在Select
子句之后执行的;所以我们需要先对数据进行排序,然后将结果集用作 Derived Table.
- 现在,我们将借助 User-defined variables(会话级持久且可访问)。在另一个派生table
user_init_vars
中,我们初始化它们
- 在
Select
子句中,我们将当前行的值与上一行的值进行比较。比较之后,我们将变量值设置为当前行的值。您可以将其视为循环技术,我们将其用于其他编程语言,如 PHP、C++、Java 等
Case .. When
表达式用于比较,并确定ladder_change
值。
查询#1
SELECT
dt.ID,
CASE WHEN DATE(@rd) <> DATE(dt.record_date) AND
dt.ladder_level > @ll
THEN 1
ELSE 0
END AS ladder_change,
@rd := dt.record_date AS record_date,
@ll := dt.ladder_level AS ladder_level
FROM (SELECT ID, record_date, ladder_level
FROM conv_example
ORDER BY ID, record_date, ladder_level) AS dt
CROSS JOIN (SELECT @rd := '',
@ll := '') AS user_init_vars;
| ID | ladder_change | record_date | ladder_level |
| ----- | ------------- | ------------------- | ------------ |
| 324 | 0 | 2016-09-15 00:00:00 | a |
| 324 | 0 | 2016-09-15 00:00:00 | b |
| 324 | 0 | 2017-04-07 00:00:00 | b |
| 324 | 0 | 2017-04-07 00:00:00 | c1 |
| 324 | 0 | 2018-09-08 00:00:00 | c1 |
| 324 | 0 | 2018-09-08 00:00:00 | e |
| 1234 | 0 | 2013-04-03 00:00:00 | |
| 1234 | 0 | 2014-07-03 00:00:00 | a |
| 1234 | 1 | 2015-04-01 00:00:00 | b |
| 1234 | 1 | 2016-09-15 00:00:00 | d |
| 1234 | 0 | 2017-02-04 00:00:00 | b |
| 1234 | 0 | 2017-04-03 00:00:00 | b |
| 1234 | 1 | 2017-04-07 00:00:00 | c1 |
| 1234 | 1 | 2018-09-08 00:00:00 | e |
| 31431 | 0 | 2013-04-03 00:00:00 | |
| 31431 | 0 | 2014-07-03 00:00:00 | a |
| 31431 | 1 | 2017-04-07 00:00:00 | c1 |
| 31431 | 1 | 2018-09-08 00:00:00 | e |
我正在尝试创建一个新变量,该变量根据一系列日期和阶梯级别 (null-E) 在 MySQL 中填充 1(真)、0(假)。
参见fiddle:http://sqlfiddle.com/#!9/9975e1
其中 record_dates 和 ladder_levels 不一定按顺序排列。我想 return ladder_change 字段通过一个 case when (?) 语句,类似于:
- 首先,仅在匹配的 ID 中查找(即仅查找 ID 324)
- 然后,类似于:
case when record_date2 > record_date1 AND (ladder_level2 < ladder_level1 OR ladder_level2>ladder_level1) then 1, else 0
- 然后,类似于:
关于如何实现这一目标的任何提示?
- 由于没有定义主键,我假设数据是在
creation_date
和ladder_level
上按顺序输入的。 记住数据以无序方式存储在MySQL。 - 首先,我们必须使用子select 查询来按要求的顺序获取数据(如上一步中突出显示的那样)。值得注意的是,
Order By
是在Select
子句之后执行的;所以我们需要先对数据进行排序,然后将结果集用作 Derived Table. - 现在,我们将借助 User-defined variables(会话级持久且可访问)。在另一个派生table
user_init_vars
中,我们初始化它们 - 在
Select
子句中,我们将当前行的值与上一行的值进行比较。比较之后,我们将变量值设置为当前行的值。您可以将其视为循环技术,我们将其用于其他编程语言,如 PHP、C++、Java 等 Case .. When
表达式用于比较,并确定ladder_change
值。
查询#1
SELECT
dt.ID,
CASE WHEN DATE(@rd) <> DATE(dt.record_date) AND
dt.ladder_level > @ll
THEN 1
ELSE 0
END AS ladder_change,
@rd := dt.record_date AS record_date,
@ll := dt.ladder_level AS ladder_level
FROM (SELECT ID, record_date, ladder_level
FROM conv_example
ORDER BY ID, record_date, ladder_level) AS dt
CROSS JOIN (SELECT @rd := '',
@ll := '') AS user_init_vars;
| ID | ladder_change | record_date | ladder_level |
| ----- | ------------- | ------------------- | ------------ |
| 324 | 0 | 2016-09-15 00:00:00 | a |
| 324 | 0 | 2016-09-15 00:00:00 | b |
| 324 | 0 | 2017-04-07 00:00:00 | b |
| 324 | 0 | 2017-04-07 00:00:00 | c1 |
| 324 | 0 | 2018-09-08 00:00:00 | c1 |
| 324 | 0 | 2018-09-08 00:00:00 | e |
| 1234 | 0 | 2013-04-03 00:00:00 | |
| 1234 | 0 | 2014-07-03 00:00:00 | a |
| 1234 | 1 | 2015-04-01 00:00:00 | b |
| 1234 | 1 | 2016-09-15 00:00:00 | d |
| 1234 | 0 | 2017-02-04 00:00:00 | b |
| 1234 | 0 | 2017-04-03 00:00:00 | b |
| 1234 | 1 | 2017-04-07 00:00:00 | c1 |
| 1234 | 1 | 2018-09-08 00:00:00 | e |
| 31431 | 0 | 2013-04-03 00:00:00 | |
| 31431 | 0 | 2014-07-03 00:00:00 | a |
| 31431 | 1 | 2017-04-07 00:00:00 | c1 |
| 31431 | 1 | 2018-09-08 00:00:00 | e |