【问题标题】:How to write a query to clean up table for given problem如何编写查询来清理给定问题的表
【发布时间】:2020-06-07 08:31:53
【问题描述】:

我有一些数据库,我需要从一个表中清理一些数据,我想相当自动地这样做。

首先是架构:这个数据库中有几个表,但我只需要专门清理一个表。

表名是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 值的所有行,这样这不是每个(天,员工)对的最后一行,我还想保留所有带有 @ 的行987654325@ 设置为 1,这不是最后一行,但也没有后跟 / 前面有另一行,根据我上面描述的约束,此列设置为 1。

这样的查询怎么写?

【问题讨论】:

  • 您没有给出完整的架构,因为没有表名。另外,您尝试自己编写此查询是什么?
  • 我正在尝试选择最后一行,但我不确定如何保留那些不在最后一行的孤 1 的“岛屿”。
  • @kamilwydrzycki 。 . .样本数据和期望的结果会有所帮助。

标签: sql sql-server select window-functions gaps-and-islands


【解决方案1】:

您可以使用窗口函数来做到这一点。基本上,对于每一天,您都希望有 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

【讨论】:

    【解决方案2】:

    如果您只想要最后一行不是“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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-09
      • 1970-01-01
      • 1970-01-01
      • 2019-11-26
      相关资源
      最近更新 更多