SQL表中N个非零前置行的总和

时间:2018-09-17 16:44:20

标签: sql sap hana

我有下表:

DATE, EMPLOYEE_ID, ILL
1.1.2016, 101, 0
1.1.2016, 102, 1
2.1.2016, 101, 1
2.1.2016, 102, 1
3.1.2016, 101, 0
3.1.2016, 102, 0

我需要编写一个SQL代码来创建一个新列,该新列将计算ILL列中一个新的(考虑DATE的)非零整数的数量。

而且必须分别针对每个员工。

原因是我需要找出一个雇员在上述日期之前患了几天病(在ILL列中缺席1天)。

这甚至可以在SQL中完成吗?

我目前正在尝试更改https://dba.stackexchange.com/questions/181773/sum-of-previous-n-number-of-columns-based-on-some-category中的查询 但是我还没有成功。

我要输出:

DATE, EMPLOYEE_ID, PREVIOUS
1.1.2016, 101, 0
1.1.2016, 102, 0
2.1.2016, 101, 0
2.1.2016, 102, 1
3.1.2016, 101, 1
3.1.2016, 102, 2
4.1.2016, 101, 0
4.1.2016, 102, 0

这是我的硕士论文的数据准备。我正在使用SAP HANA STUDIO。

4 个答案:

答案 0 :(得分:2)

您可以通过为每个以0分隔的组分配一个组号来实现。然后,您将在组中使用bytes.decode()

您可以使用累计和来计算组号。因此,查询看起来像:

row_number()

答案 1 :(得分:0)

您可以使用累积(窗口)计数:

SELECT date,
       employee_id,
       ill, 
       COUNT(CASE ill WHEN 1 THEN 1 END) OVER 
            (PARTITION BY employee_id
             ORDER BY date ASC
             ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT_ROW)
FROM   mytable

答案 2 :(得分:0)

简单的自我联接将有助于解决此问题,而不仅仅是使用如下的SUM()和GROUP BY

select 
    t1.date, 
    t1.EMPLOYEE_ID, 
    t1.ill, 
    coalesce(sum(t2.ill),0) as previous
from testdata as t1
left join testdata as t2
    on t1.EMPLOYEE_ID = t2.EMPLOYEE_ID and
       t1.date > t2.date
group by t1.date, t1.EMPLOYEE_ID, t1.ill
order by t1.date, t1.EMPLOYEE_ID;

替代查询可以如下所示,其结果与上述相同

SELECT date,
       employee_id,
       ill, 
       coalesce(
       SUM(ill) OVER 
            (PARTITION BY employee_id
             ORDER BY date ASC
             ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
       ), 0) as Previous
FROM   testdata

据您所知,请注意。您似乎要询问该雇员在该天之前连续生病的天数。我说得对吗?

答案 3 :(得分:0)

如果您想查找某个雇员当前日期之前的连续生病天数,可以使用followin SQL查询

with newdata as (
select 
    *,
    case 
        when ill = 1 and lag(ill,1,0) over (partition by EMPLOYEE_ID order by date) = 0 then 1 end as illdays
from testdata
), empdata as (
select
    date, EMPLOYEE_ID, ill,
    case when ill = 1 and lag(ill,1,0) over (partition by EMPLOYEE_ID order by date) = 1 then coalesce(lag(illdays,1,0) over (partition by EMPLOYEE_ID order by date),0)+1 else illdays end as illdays
from newdata
)
select
date, EMPLOYEE_ID, ill,
coalesce( lag(illdays,1,0) over (partition by EMPLOYEE_ID order by date), 0) as previous
from empdata
order by EMPLOYEE_ID, date;

在详细介绍SQL查询之前,这是上面SqlScript执行的输出

enter image description here

首先,我使用带有WITH子句的Common Table Expression CTE expression in SQLScript代替了子选择语句

我经常在代码中使用SQL Lag() function来使用Lag()函数后面的Partition By和Order By子句以给定的顺序读取以前的记录。由于Lag()函数是标准的SQL函数,因此您可以在不同的数据库平台上使用它

该查询实际上是在newdata CTE中找到一个起点并存储病期列。

然后,我在以下empdata CTE中更新此值。这部分确定彼此相继发生的重复疾病天

最后的CTE用于显示病假并准备最终结果

我希望对您有帮助