【问题标题】:Reduce consecutive rows with the same value in a column to a single row将列中具有相同值的连续行减少为单行
【发布时间】:2019-09-19 10:26:54
【问题描述】:

我正在尝试创建一个从生物识别设备接收数据的生物识别考勤系统。

从设备接收到的考勤表的结构如下所示。

该表最初有很多数据,其中有多个 emp_no,但我创建了一个存储过程,可以提取特定日期的一名员工的详细信息,如上所示。 现在面临的挑战是,我需要分析此表并对其进行重组(重新创建另一个表),以便它具有交替的签入和签出(每次签入后必须有一个签出,反之亦然)和 连续入住,我应该取较早的,而连续退房的,我应该取最新的。 任何关于如何解决这个问题的想法都将不胜感激。 谢谢。

【问题讨论】:

  • 样本数据最好显示为formatted text。请参阅here,了解有关如何创建漂亮表格的一些提示。

标签: sql postgresql window-functions


【解决方案1】:

使用窗口函数lag()lead()

select emp_id, att_date, att_time, status
from (
    select 
        emp_id, att_date, att_time, status, 
        case 
            when status = 'checkin' then lag(status) over w is distinct from 'checkin'
            else lead(status) over w is distinct from 'checkout'
        end as visible
    from my_table
    window w as (partition by emp_id, att_date order by att_time)
    ) s
where visible

Db<>fiddle.

【讨论】:

  • 感谢您的快速回复。我会去阅读更多关于windows函数的内容。
  • 但是,我实际上想要实现的是,如果有两个或多个连续签入,它应该只取第一个而忽略其他的。如果有连续结帐,则应选择最新的结帐并忽略其余结帐。所以结果表应该有更少的记录交替签入和签出。
  • 好的,请参阅更新后的答案。在问题中放置预期的输出可能有助于避免误解。并且始终以文本形式提供数据结构和示例数据。
  • 我仍在学习如何在 StackOverflow 中编写和构建我的答案,对此感到抱歉。非常感谢,我一直在忙了一整天,到现在都没有用。似乎我有必要通过“窗口函数”来掌握这些概念。出于好奇,有没有办法重组生成的表,而不是有一个交替签入和签出的状态列,它应该有 check_in 和 check_out 列以及它们各自的时间?
  • db<>fiddle
猜你喜欢
  • 2021-09-12
  • 2014-04-21
  • 1970-01-01
  • 1970-01-01
  • 2020-05-03
  • 1970-01-01
  • 2021-08-05
  • 2011-09-18
  • 2015-09-04
相关资源
最近更新 更多