GROUP BY 日期范围日期

Posted

技术标签:

【中文标题】GROUP BY 日期范围日期【英文标题】:GROUP BY date range date 【发布时间】:2020-11-27 19:49:32 【问题描述】:

我有一个工作层次结构的大表(大约 1500 万行)。 当前的层次结构列表每天有 1 个条目,时间跨度约为 2 年。

我正在尝试组合这些条目以捕获除日期之外的任何列更改,并编译为 1 个条目。

我在 Table1 中包含了我的表格的示例。以及我希望它在 Table2 中的样子。

此外,这些表是简单的版本,大约有 20 列,我想在任何列中的任何内容发生变化时创建一个条目。

我可以在整个表上执行 GROUP BY 或 DISTINCT,而不是获取记录的日期 - 但不知道如何附加这些不同记录的最小和最大日期?

我目前正在使用 SSMS v18.0

TIA。

表1

+------------+---------+-------+------------+
|    Date    |  Name   |  ID   | Supervisor |
+------------+---------+-------+------------+
| 2020-01-01 | Chad    | 12345 | John       |
| 2020-01-02 | Chad    | 12345 | John       |
| 2020-01-03 | Chad    | 12345 | John       |
| 2020-01-04 | Chad    | 12345 | Stephen    |
| 2020-01-05 | Chad    | 12345 | Stephen    |
| 2020-01-06 | Chad    | 12345 | Stephen    |
| 2020-01-07 | Chad    | 12345 | Stephen    |
| 2020-01-08 | Chad    | 12345 | Stephen    |
| 2020-01-09 | Chad    | 12345 | Stephen    |
| 2020-01-10 | Chad    | 12345 | Stephen    |
| 2020-01-01 | Patrick | 54321 | John       |
| 2020-01-02 | Patrick | 54321 | John       |
| 2020-01-03 | Patrick | 54321 | John       |
| 2020-01-04 | Patrick | 54321 | John       |
| 2020-01-05 | Patrick | 54321 | John       |
| 2020-01-06 | Patrick | 54321 | John       |
| 2020-01-07 | Patrick | 54321 | Stephen    |
| 2020-01-08 | Patrick | 54321 | Stephen    |
| 2020-01-09 | Patrick | 54321 | Stephen    |
| 2020-01-10 | Patrick | 54321 | Stephen    |
+------------+---------+-------+------------+

表 2

+------------+------------+---------+-------+------------+
| StartDate  |  EndDate   |  Name   |  ID   | Supervisor |
+------------+------------+---------+-------+------------+
| 2020-01-01 | 2020-01-03 | Chad    | 12345 | John       |
| 2020-01-04 | 2020-01-10 | Chad    | 12345 | Stephen    |
| 2020-01-01 | 2020-01-06 | Patrick | 54321 | John       |
| 2020-01-07 | 2020-01-10 | Patrick | 54321 | Stephen    |
+------------+------------+---------+-------+------------+

【问题讨论】:

您的表格图像没有用。请以文本形式提供信息。只有在没有其他方法可以证明问题时才应使用图像。见Please do not upload images of code/errors when asking a question.。在制作edit 时,请同时添加您自己解决问题的努力以及您正在使用的特定 DBMS 的标签。谢谢。 嗯,你解决了我所问问题的一半。您可以为您正在使用的特定 DBMS 和您编写的 SQL 添加标签以尝试自己现在解决问题吗? @KenWhite 我强烈建议您调整应对方法。它们非常磨蚀。显然基于我个人资料的统计信息 - 我是在这里发帖的新手。然而,在我弄清楚“你问的一半”的时间里,有 2 个人能够用答案和解决方案做出回应。虽然我非常感谢论坛上的人,并尽量遵守适当的礼仪 - 肯定有更好的方法来处理您的方法和响应。 我强烈建议您学习接受建设性的建议,这些建议既可以让您更快地回答这个问题,又可以通过帮助您了解网站的运作方式来改善您未来的体验。不客气,顺便说一句。如果您脸皮薄,以至于有人向您询问其他信息会伤害您的感情或冒犯您,那么像 SO 这样的网站可能不适合您。 【参考方案1】:

这是一个孤岛问题。您可以使用行号的差异:

select person, id_number, supervisor, min(date), max(date)
from (select h.*,
             dense_rank() over (order by date) as seqnum,
             row_number() over (partition by person, id_number, supervisor order by date) as seqnum_2
      from hierarchy h
     ) h
group by (seqnum - seqnum_2), person, id_number, supervisor

【讨论】:

非常感谢 - 这是完美的!现在申请整个表格并查看处理时间:)【参考方案2】:

我认为您需要 LAG 窗口功能。

Oracle: https://oracle-base.com/articles/misc/lag-lead-analytic-functions#lag
SQLite: https://www.sqlitetutorial.net/sqlite-window-functions/sqlite-lag/

像这样:

select *
from (
  select 
    t.date start_date,  
    lag(date, 1) end_date,
    person,
    id_number,
    supervisor,
    case when
      decode(person, lag(person, 1), 1, 0) = 1 or
      decode(supervisor, lag(supervisor, 1), 1, 0) = 1 or
      decode(column_to_check_1, lag(column_to_check_1, 1), 1, 0) = 1 or
      decode(column_to_check_2, lag(column_to_check_2, 1), 1, 0) = 1
    then 1 else 0 end change_detect
  from (
    select * 
    from table1 
    order by person, date) t
  )
where change_detect = 1
order by date, person;

【讨论】:

以上是关于GROUP BY 日期范围日期的主要内容,如果未能解决你的问题,请参考以下文章

具有日期范围条件的 Group By 和 SUM 的 sql

带有 MIN 和 MAX 的 GROUP BY - 属于解决方案的日期范围

我们可以使用group by和where字段名相同的条件

MySQL 实体框架 Group 和 Select By Date

日期范围在 WHERE 的 ORDER BY 的 MySQL 索引

如何连接具有不同 GROUP BY 级别的两个查询,使一些记录为空