在表中查找最小和最大数据列

Posted

技术标签:

【中文标题】在表中查找最小和最大数据列【英文标题】:Find min and max data column in Table 【发布时间】:2021-10-07 00:16:09 【问题描述】:

我有一个表格,可以准确地指定每个员工在特定办公室的日期和时间。

EmployeeTable 看起来像这样:

id EmployeeID DateP TimeP
1 11111 1397/01/02 01:30
2 11111 1398/05/09 05:30
3 11111 1398/06/07 05:10
4 22222 1398/08/09 06:12
5 22222 1399/02/01 07:15
6 11111 1399/07/02 08:51
7 11111 1399/08/06 12:20
8 33333 1399/09/04 20:01
9 33333 1399/12/08 22:05
10 33333 1400/01/01 23:11
11 33333 1400/02/05 14:10
12 22222 1400/04/05 16:25

我想准确地选择每个员工在办公室时的最小和最大日期和时间:

id EmployeeID MinDateP TimeMinDateP MaxDateP TimeMaxDateP
1 11111 1397/01/02 01:30 1398/06/07 05:10
2 22222 1398/08/09 06:12 1399/02/01 07:15
3 11111 1399/07/02 08:51 1399/08/06 12:20
4 33333 1399/09/04 20:01 1400/02/05 14:10
5 22222 1400/04/05 16:25 1400/04/05 16:25

我的SQL代码是:

with tab1 as 
(
    select * 
    from EmployeeTable
), tab2 as 
(
    select 
        t1.*,
        case when lag(t1.EmployeeID) over(order by t1.id) is null then 1
            when lag(t1.EmployeeID) over(order by t1.id) = t1.EmployeeID then 0
            else 1
       end lg
  from tab1 t1
)
, tab3 as (
select t1.*,
       sum(t1.lg) over(order by t1.id) grp
  from tab2 t1
)
select t1.EmployeeID,
       min(t1.DateP) as min,
       TimeP,
       max(t1.DateP)as max,
       TimeP
  from tab3 t1
 group by t1.EmployeeID, t1.grp

但上面的代码有错误。 每个人都可以帮助我吗?

【问题讨论】:

如果您遇到错误,您需要发布错误! 为什么将日期和时间存储在不同的列中? 【参考方案1】:

这是一个空白和孤岛问题。解决此问题的一种方法是使用行数差异法:

WITH cte AS (
    SELECT *, ROW_NUMBER() OVER (ORDER BY DateP, TimeP) rn1,
              ROW_NUMBER() OVER (PARTITION BY EmployeeID ORDER BY DateP, TimeP) rn2
    FROM EmployeeTable
),
cte2 AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY EmployeeID, rn1 - rn2
                                 ORDER BY DateP, TimeP) rn_first,
              ROW_NUMBER() OVER (PARTITION BY EmployeeID, rn1 - rn2
                                 ORDER BY DateP DESC, TimeP DESC) rn_last
    FROM cte
)

SELECT
    EmployeeID,
    MAX(CASE WHEN rn_first = 1 THEN DateP END) AS MinDateP,
    MAX(CASE WHEN rn_first = 1 THEN TimeP END) AS TimeMinDateP,
    MAX(CASE WHEN rn_last = 1  THEN DateP END) AS MaxDateP,
    MAX(CASE WHEN rn_last = 1  THEN TimeP END ) AS TimeMaxDateP
FROM cte2
GROUP BY
    EmployeeID,
    rn1 - rn2
ORDER BY
    MIN(DateP),
    MIN(TimeP);

请注意,如果您使用单个日期时间列来表示日期和时间,则完全不需要第二个 CTE 中的逻辑。像现在这样分开日期和时间通常是没有好处的。

【讨论】:

您好,非常感谢您的帮助。但是我不希望对时间进行排序,因为确切地需要第一个日期记录中的时间和最后一个日期记录中的时间。你能帮帮我吗? 您提供的示例数据按日期和时间升序排列。我的 ORDER BY 子句只是保持相同的顺序。 请注意问题。我想从主表中找到输出结果。如何从日期的开始行和日期的结束行找到时间? 澄清一下,你试过我的答案了吗? 是的,先生。我正在处理您建议的代码,但不幸的是它改变了 TimeP 列。我不需要对 TimeP 列进行排序。这意味着当代码从每个 EmployeeID 中找到开始和结束日期时,就会准确显示每个 EmployeeID 所在行的时间。您的代码结果是:

以上是关于在表中查找最小和最大数据列的主要内容,如果未能解决你的问题,请参考以下文章

查找表中数据的最小最大值和平均值

获取数据,在表中查找,获取匹配数据,导出 [关闭]

在表中查找缺失的序列

在表中为每个数据库查找具有空值的列[关闭]

sql查询 如何获取查找某ID的一条记录在表中是第几条记录

认真对待每一天