如何获取 SQL 中的第一个非 NULL 值?

Posted

技术标签:

【中文标题】如何获取 SQL 中的第一个非 NULL 值?【英文标题】:How to get the first non-NULL value in SQL? 【发布时间】:2019-12-15 20:30:53 【问题描述】:

我有三列数据。一列有 ID,第二列有日期,第三列有 BMI 值。我想创建第四列,该列具有基于日期(升序)的第一列,第三列不为空或避免为空。

到目前为止,我已经尝试过以普通形式的 first_value,但它不起作用。我尝试在 case when 语句中设置 first_value 子集为

CASE 
  WHEN BMI IS NOT NULL THEN (FIRST_VALUE(BMI) OVER PARTITION BY PID ORDER BY DATE)) 
  ELSE 0 
END AS FIRSTNOTNULLVALUE_BMI

给我0。

id    date         BMI 
1   2000-01-01    NULL
1   2003-05-01    18.1
1   2002-07-15    25.8
2   2009-09-25    NULL
2   2015-04-18    23.5

有什么建议吗??

【问题讨论】:

发布样本数据和预期结果以澄清。 请用您正在使用的数据库标记您的问题:mysql、sql-server、postgresql...? 发布了示例数据并为数据库添加了标签。 您的样本数据在 BMI 中不包含任何空值。发布带有空值和预期结果的样本数据。 另外Mysql和SQLite也不一样。仅标记您使用的数据库。 【参考方案1】:

您可以将CASE 放在FIRST_VALUEORDER BY 中。 然后 null 将在该函数的最后排序。

create table test
(
  pid int,
  pdate date,
  BMI decimal(4,1)
)

insert into test (pid, pdate, BMI) values
  (1, '2000-01-01', NULL)
, (1, '2003-05-01', 18.5)
, (1, '2002-07-15', 24.9)
, (2, '2009-09-25', NULL)
, (2, '2015-04-18', 21.7)
;
select *
, first_value(BMI) over (partition by pid order by case when BMI is not null then 1 else 2 end, date(pdate)) as firstBMI
from test
order by pid, pdate
进程号 |更新 |体重指数 |第一BMI :-- | :--------- | :--- | :-------- 1 | 2000-01-01 | | 24.9 1 | 2002-07-15 | 24.9 | 24.9 1 | 2003-05-01 | 18.5 | 24.9 2 | 2009-09-25 | | 21.7 2 | 2015-04-18 | 21.7 | 21.7

db小提琴here

【讨论】:

非常感谢!你引导我走向正确的方向。我将上面的代码编辑为 select *, first_value(bmi) over(partition by pid order by case when bmi is null then 1 else 0 end) as firstnonnull_bmi from vitals_f2 order by pid; @PrajwalManiPradhan Thx,我更正了答案。顺便说一句,仅CASE 的订单不足以获得最旧的非空 BMI【参考方案2】:

您可以将您的表与恢复第一个非空 BMI 的子查询结合起来,按日期计算:

select
    t.*,
    x.bmi first_non_null_bmi
from mytable t
cross join (select bmi from mytable where bmi is not null order by date limit 1) x

【讨论】:

【参考方案3】:

我认为你可以做这样的事情..也许会工作..或者给你任何想法

   THEN (select BIM = row_number() over (partition by BIM order by DATE desc/asc) 
      from Products)
ELSE..

【讨论】:

【参考方案4】:

您可以只使用子查询:

select bmi.*,
       (select bmi2.bmi
        from bmi bmi2
        where bmi2.id = bmi.id and bmi2.bmi is not null
        order by bmi2.date
        limit 1
       ) as first_bmi
from bmi;

【讨论】:

以上是关于如何获取 SQL 中的第一个非 NULL 值?的主要内容,如果未能解决你的问题,请参考以下文章

如何访问从sql函数获取的java中的多个返回值

sQL 数据库如何获取一列的非重复值

用 Redshift 中的第一个非空跟随值填充缺失值

如果 json 数组中的某个值返回 null,如何返回下一个非 null 的 json 值?

从 SQL 函数获取单个值时,如何将 NULL 更改为 0?

如何使用 SQL 获取列中每个分区的第一个和最后一个值