【问题标题】:SQL performing day difference by matching valueSQL通过匹配值执行天差
【发布时间】:2017-12-14 23:20:35
【问题描述】:

我的目标是获得1st OLD1st NEW 状态达到1st END 的持续时间。

例如:Table1

ID   Day STATUS
111   1   NEW
111   2   NEW
111   3   OLD
111   4   END
111   5   END
112   1   OLD
112   2   OLD
112   3   NEW
112   4   NEW
112   5   END
113   1   NEW
113   2   NEW

期望的结果是:

STATUS Count

NEW 2 (1 for ID 111-New on day 1 to End on day 4,and 1 for 112-new on day 3 to End on day 5)

OLD 2 (1 for ID 111-Old on day 3 to End on day 4, and 1 for 112-OLD on day 1 to End on day 5)

【问题讨论】:

  • 标记正在使用的 dbms。例如:Oracle、MySQL、SQL Server、Postgres 等
  • 哦,我目前正在使用 ms 访问,但很快将迁移到 SQL 服务器。任何一个都可以。我对方法更好奇。 :)
  • TylerNG 我们现在需要知道数据库的“品牌”是什么,因为虽然“sql”是一个标准,但不同的数据库以不同的方式实现它。那么它是例如 MySQL 吗?甲骨文? SQLite?后格雷斯?等
  • MYSQL 可以工作

标签: sql count days


【解决方案1】:

以下是 T-SQL (SQL Server),在 MySQL 中不可用。 dbms 的选择在一个问题中至关重要,因为有很多 dbms 特定的选择要做。下面的查询需要使用“窗口函数”row_number() over()common table expression,它们在 MySQL 中都不存在(但总有一天会出现)。此解决方案还使用cross apply,它(迄今为止)是特定于 SQL Server 的,但在 Postgres 和 Oracle 12 中有使用 lateral joins 的替代方案。

SQL Fiddle

MS SQL Server 2014 架构设置

CREATE TABLE Table1
    (id int, day int, status varchar(3))
;

INSERT INTO Table1
    (id, day, status)
VALUES
    (111, 1, 'NEW'),
    (111, 2, 'NEW'),
    (111, 3, 'OLD'),
    (111, 4, 'END'),
    (111, 5, 'END'),
    (112, 1, 'OLD'),
    (112, 2, 'OLD'),
    (112, 3, 'NEW'),
    (112, 4, 'NEW'),
    (112, 5, 'END'),
    (113, 1, 'NEW'),
    (113, 2, 'NEW')
;

查询 1

with cte as (
      select
              *
      from (
        select t.*
              , row_number() over(partition by id, status order by day) rn
        from table1 t
            ) d
      where rn = 1
      )
select 
       t.id, t.day, ca.nxtDay, t.Status, ca.nxtStatus   
from cte t
outer apply (
    select top(1) Status, day
    from cte nxt
    where t.id = nxt.id
    and t.status = 'NEW' and nxt.status = 'END'
    order by day
    ) ca (nxtStatus, nxtDay)
where nxtStatus IS NOT NULL or Status = 'OLD'
order by id, day

Results

|  id | day | nxtDay | Status | nxtStatus |
|-----|-----|--------|--------|-----------|
| 111 |   1 |      4 |    NEW |       END |
| 111 |   3 | (null) |    OLD |    (null) |
| 112 |   1 | (null) |    OLD |    (null) |
| 112 |   3 |      5 |    NEW |       END |

如您所见,计算 Status 列将导致 NEW = 2 和 OLD = 2

【讨论】:

  • 谢谢!一旦我开始使用 ssms,我会尝试一下 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-21
  • 1970-01-01
相关资源
最近更新 更多