SQL窗口函数按空值分区

时间:2018-04-03 07:44:39

标签: sql db2 window-functions cumulative-sum

我有一个数据集:

year     id
NULL     123
NULL     124
NULL     125
1932     126
1932     127
1933     128
1933     129
1934     130

我想创建一个运行计数,其中我将NULL个值组作为一个组,另一个组具有non-null值,即。

year    count
NULL    3
1932    2
1933    4
1934    5

我尝试通过union两个windows function数据集执行此操作,即:

select distinct year, 
count(id) over (order by year asc)
from data
where year is null

union

select distinct year, 
count(id) over (order by year asc)
from data
where year is not null;

我想知道是否有一种更清洁的方法,例如:

select distinct year, 
count(id) over (partition by <whether year is null condition> order by year 
asc)
from data;

我的sql版本是db2。

5 个答案:

答案 0 :(得分:2)

这是一个不使用分析函数的选项:

SELECT DISTINCT t1.col,
    CASE WHEN t1.col IS NULL
         THEN
         (SELECT COUNT(*) FROM data t2 WHERE t1.year IS NULL AND t2.year IS NULL)
         ELSE
         (SELECT COUNT(t2.id) FROM data t2
          WHERE t1.year = t2.year OR (t2.id <= t1.id AND t2.year IS NOT NULL)) 
    END cnt
FROM data t1;

答案 1 :(得分:2)

试试这个:

DECLARE @tab TABLE(year INT, id INT)

INSERT INTO @tab VALUES( NULL,123)
INSERT INTO @tab VALUES(NULL,124)
INSERT INTO @tab VALUES(NULL,125)
INSERT INTO @tab VALUES(1932,126)
INSERT INTO @tab VALUES(1932,127)
INSERT INTO @tab VALUES(1933,128)
INSERT INTO @tab VALUES(1933,129)
INSERT INTO @tab VALUES(1934,130)

SELECT D.year, MAX(D.RN)Count 
FROM(
    SELECT year,SUM(1) OVER(PARTITION BY CASE WHEN year IS NULL THEN 1 ELSE 0 END ORDER BY id) RN FROM @tab
    )D
GROUP BY D.year

<强>输出:

year    Count
NULL    3
1932    2
1933    4
1934    5

答案 2 :(得分:2)

Union all将获得你所需的输出,它很难实现这一目标,但却会获得输出

declare @table table (year int, id int)
insert @table
(year,id)
select 
NULL  ,   123 union all
select NULL  ,   124 union all
select NULL   ,  125 union all
select 1932   ,  126 union all
select 1932   ,  127 union all
select 1933   ,  128 union all
select 1933   ,  129 union all
select 1934   ,  130


select Runningtotal, year from
(

select SUM(count) over (order by year) RunningTotal ,year from 
(
select count(*) count,year from @table group by year ) x
where year is not null

union all 

select SUM(count) over (order by year) Runningtotal ,year from 
(
select count(*) count,year from @table group by year ) x
where year is  null
) y  order by year 

答案 3 :(得分:1)

方法1:

{{1}}

答案 4 :(得分:1)

方法2:

select distinct year,                                             
( select count(*) NB from tmpxx f2                                
  where f1.year is null and f2.year is null or f1.year>=f2.year   
) nb                                                              
from tmpxx f1