SQL windows 函数按空值划分

SQL windows function partition by null values

我有一个数据集:

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

我尝试通过两个 windows function 数据集的 union 来做到这一点,即:

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.

这里有一个不使用解析函数的选项:

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;

试试这个:

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

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 

方法一:

select distinct year, f3.NB                               
from tmpxx f1                                             
left outer join lateral                                   
(                                                         
  select count(*) NB from tmpxx f2                        
  where f1.year is null and f2.year is null or            
        f1.year>=f2.year                                  
) f3 on 1=1            

方法二:

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