【问题标题】:Select Single Field in two Column (Mysql)在两列中选择单个字段(Mysql)
【发布时间】:2017-06-17 11:54:40
【问题描述】:

我们正在使用 Mysql 数据库,并且我们有单个表是 employee_transaction

employee_transaction

id |  employee_id | date            | transaction_type
------------------------------------------------------
1  | 1            | 2015-01-01      | 1
2  | 1            | 2015-07-01      | 1 
3  | 1            | 2015-12-31      | 0
4  | 2            | 2014-02-01      | 1 
5  | 1            | 2016-04-01      | 1
6  | 2            | 2014-11-30      | 0
7  | 1            | 2016-08-01      | 1
8  | 1            | 2016-10-31      | 0 

等等。

要获得正确的结果,需要满足以下条件:-

  • 任何员工的第一个 transaction_type 始终为 1。
  • 任何员工都不能有连续的 transaction_type=0。
  • 两个连续的transaction_type的结果如下。这些 结果适用于一名员工

    1. 如果 Transaction_type=1。 那么 start_date=第一个交易日期,end_date=第二个交易日期-1,transaction_type=1。
    2. 如果第一个 Transaction_type=1 并且下一个 transaction_type=0。 那么 start_date=第一个交易日期,end_date=第二个交易日期 和 transaction_type=1。
    3. 如果第一个 Transaction_type=0 并且下一个 transaction_type=1。 那么 start_date=第一笔交易日期+1,end_date=第二笔交易 date-1 和 transaction_type=0。
    4. 如果在transaction_type=0之后没有找到交易。 那么 start_date=第一个交易日期+1,end_date=空和 transaction_type=0。

我们需要 employee_transaction 表的以下输出的Query

  employee_id |  start_date     | end_date       | transaction_type
------------------------------------------------------
 1            | 2015-01-01      | 2015-06-30     | 1
 1            | 2015-07-01      | 2015-12-31     | 1 
 1            | 2016-01-01      | 2016-03-31     | 0
 1            | 2016-04-01      | 2016-07-31     | 1
 1            | 2016-08-01      | 2016-10-31     | 1
 1            | 2016-11-01      | (Null)         | 0 
 2            | 2014-02-01      | 2014-11-30     | 1

提前致谢。

如果您有任何疑虑/需要澄清,请回复我。

【问题讨论】:

  • 我删除了不兼容的数据库标签。请标记您真正使用的数据库。此外,使用您提供的数据order by employee_id, start_date) 有效。规则背后的原因有点不清楚。交易是什么意思?
  • 嗨@GordonLinoff,我已经更新了问题中的所有细节。感谢您的建议。

标签: mysql sql


【解决方案1】:

使用相关子查询获取每个employee_id 的下一个日期、下一个事务类型(按日期排序)。然后根据提到的条件使用case 表达式。

select employee_id
,case when (transaction_type=0 and nxt_t_type=1) or (transaction_type=0 and nxt_t_type is null) then dt+interval '1' day
 else dt
 end as dt
,case when nxt_t_type=1 then nxt_dt-interval '1' day 
      when transaction_type=1 and nxt_t_type=0 then nxt_dt
      when transaction_type=0 and nxt_t_type is null then null
 end as nxt_dt
,transaction_type
from (select t1.*
      ,(select t2.dt from t t2 where t1.employee_id=t2.employee_id and t2.dt > t1.dt 
        order by t2.dt limit 1) as nxt_dt
      ,(select t2.transaction_type from t t2 where t1.employee_id=t2.employee_id and t2.dt > t1.dt 
        order by t2.dt limit 1) as nxt_t_type
      from t t1
     ) x

Sample Demo

【讨论】:

  • 非常感谢您的回答。我知道这是糟糕的数据库设计,但会更改数据库。如果我们能得到结果。这对我们真的很有帮助。
  • 嗨,再次,在提供的场景中,日期在有序中,如果它们不在有序中,那么我们需要做什么。我们需要与您提供给我的结果相同的结果。提前致谢。
【解决方案2】:

这是一个使用相关子查询来连接每个员工的连续日期和状态信息的查询:

select
    f.emp_id, f.trans_date, f.trans_type,
    (select trans_date from emp_trans
    where emp_id=f.emp_id and trans_date = (select min(trans_date)
                                       from emp_trans where emp_id=f.emp_id
                                       and trans_date > f.trans_date)
    ) as end_trans_date,
    (select trans_type from emp_trans
    where emp_id=f.emp_id and trans_date = (select min(trans_date)
                                       from emp_trans where emp_id=f.emp_id
                                       and trans_date > f.trans_date)
    ) as end_trans_type
from emp_trans as f;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-21
    相关资源
    最近更新 更多