sql—如何编写查询来清除给定问题的表

ss2ws0br  于 2021-07-26  发布在  Java
关注(0)|答案(2)|浏览(266)

我有一些数据库,我需要清理一些数据从一个表,我想这样做相当自动。
首先是模式:这个数据库中有几个表,但我只需要清理一个表。
表名为 CollectedProducts :

[Id] [int] IDENTITY(1,1) NOT NULL,
[Date] [date] NOT NULL,
[Time] [time](7) NOT NULL,
[BouquetId] [int] NOT NULL,
[EmployeeId] [int] NOT NULL,
[ProductionEnd] [bit] NOT NULL

我对最后一个专栏很感兴趣, ProductionEnd ,表示如果特定员工在给定的一天内完成了生产。
此列的逻辑约束是这样的:在给定的一天的生产结束时,必须至少有一行将此列设置为1。所以这基本上是员工在某一天的最后一行。
在一天中,还可以将其他行设置为1,表示员工的休息时间更长。
它的后面或前面不能有另一个值设置为1的行。
现在考虑到这些约束,我想选择所有具有无效 ProductionEnd 值,使其不是每个(day,employee)对的最后一行,并且我还希望保留所有具有 ProductionEnd 设置为1,这不是最后一行,但也不是紧跟在另一行后面/前面,根据我上面描述的约束,该列设置为1。
如何编写这样的查询?

mrwjdhj3

mrwjdhj31#

您可以使用窗口函数来实现这一点。基本上每天你都想和 ProductionEnd = 1 以及其他行中存在的时间和 ProductionEnd = 1 并且不存在时间和时间较晚的行 ProductionEnd = 0 .
你可以这样说:

select *
from (
    select
        cp.*,
        sum(ProductionEnd) 
            over(partition by EmployeeId, Date order by Time desc) nbProdEnd,
        sum(case when ProductionEnd = 1 then 0 else 1 end)
            over(partition by EmployeeId, Date order by Time desc) nbNonProdEnd
    from CollectedProducts cp
) t
where nbProdEnd > 1 and nbNonProdEnd = 0
xam8gpfp

xam8gpfp2#

如果您只需要最后一行不是“1”的日期/员工对,那么您可以使用 first_value() . 下面获取雇员日期的所有行:

select cp.*
from (select cp.*,
             first_value(productionEnd) over (partition by EmployeeId, Date order by Time desc) as last_productionEnd
      from CollectedProducts cp
     ) cp
where last_productionEnd <> 1;

如果您只想要最后一个,可以使用:

select cp.*
from (select cp.*,
             row_number() over (partition by EmployeeId, Date order by Time desc) as seqnum
      from CollectedProducts cp
     ) cp
where seqnum = 1 and last_productionEnd <> 1;

相关问题