SQL进阶:如何跳过多个NULL值取第一个非NULL值?

news2024/11/29 20:08:31

NULL

  • 一、问题描述
  • 二、ORACLE
    • <一>、last_value () over ()
    • <二>、lag () over()
    • <三>、相关子查询
  • 三、MYSQL
    • <一>、全局变量
    • <二>、coalesce() + lag() over()
    • <三>、相关子查询
    • <四>、 recursive
    • <五>、lag() over() + min() over() / max() over()

一、问题描述

  • 假如某张表中某个列有多个null值,如何跳过这多个null值取第一个不为空的值去填充,如下述表格所示
productsale_daeamount
12024/01/01100
12024/01/02200
12024/01/03
12024/01/04
22024/01/01200
22024/01/02
22024/01/03300
22024/01/04

某产品当天sale_date为空的销售价格取上一天的填充,最终想展示的如下述表格所示

productsale_daeamount
12024/01/01100
12024/01/02200
12024/01/03200
12024/01/04200
22024/01/01200
22024/01/02200
22024/01/03300
22024/01/04300

二、ORACLE

<一>、last_value () over ()

  • last_value()是sql中的一个窗口函数,用于获取窗口中的最后一个值,默认计算范围是第一行到当前行,有窗口是窗口内的第一行到当前行
select product,
	   sale_date,
	   amount,
	   last_value(amount ignore nulls)over(partition by product order by sale_date) as last_amount
  from test
  • 如上述代码所示,按照产品分组,销售日期排序,若是有值则自己就是组内的最后一个值,把自己填充,若为NULL,则用IGNORE NULLS语法忽略NULL值,则用上一个值填充

<二>、lag () over()

  • lag()也是sql中的窗口,用于获取当前行的前几条记录,默认为上一条记录
select product,
	   sale_date,
	   amount,
	   coalsece(amount,lag(amount ignore nulls)over(partition by product order by sale_date)) as last_amount
  from test

如上述代码所示,按照产品分组,销售日期排序,用了coalesce()函数,表示若是amount为空,则取lag(),默认是取上一条,上一条若也为空,则用IGNORE NULLS语法忽略NULL值,再取上一个填充,直到找到非NULL值

<三>、相关子查询

select product,
	   sale_date,
	   amount,
	   (select  amount
	     from (
			select amount 
			  from test t1 
			 where t1.product = t.product
			   and t1.sale_date <= t.sale_date
			   and amount is not null 
			 order by t1.sale_date desc
			) 
		where rownum <= 1) as last_amount
  from test t
  • 用一个内部的子查询找到product相同,日期<=当前日期,且amount不为空的第一条

三、MYSQL

  • MYSQL中虽然也有last_value()和lag()函数,但是不支持IGNORE NULLS选项,所以不能够直接用这两个函数实现

<一>、全局变量

  • mysql中@表示全局变量,可以用全局变量递归实现
set @last_non_null := NULL;

with tmp as (
	selet product,
	      sale_date,
	      amount,
	      if(amount is null, @last_non_null := coalesce(@last_non_null,amount),
	      @last_non_null := amount) as last_amount
	 from test
    order by product,sale_date
)
	select product,
	       sale_date,
	       amount,
	       cast(last_amount as float) as last_amount
	  from tmp
  • 如上述代码所示,order by
    product,sale_date是保证同个产品是按照sale_date排序的,也就是按照产品分组,销售日期排序
  • set @last_non_null : NULL表示设置全局变量last_non_null为NULL,后面的sql会用到这个变量
  • amount不为空的时候,last_non_null直接赋值amount返回;当amount为空的时候,last_non_null此时没有被赋值,直接返回,返回的就是上一个非空值

<二>、coalesce() + lag() over()

  • 上面说到Mysql的lag() over()是不支持ignore nulls选项的,那如何实现忽略null值呢?可以用一种笨方法,就是前面几条都写出来
select product,
	   sale_date,
	   amount,
	   coalesce(amount,
			lag(amount,1)over(partition by product order by sale_date),
			lag(amount,2)over(partition by product order by sale_date),
			lag(amount,3)over(partition by product order by sale_date),
			...
		)
  from test
  • 上述方法可以适用于连续NULL值比较少的情况,如果连续NULL值比较多,还是不建议的

<三>、相关子查询

  • Mysql的相关子查询和Oracle逻辑是一样的,只不过取第一条的时候稍有不同,mysql是用limit
select product,
       sale_date,
       amount,
       (select amount
         from test t1
        where t1.product = t.product
          and t1.sale_date <= t.sale_date 
        order by t1.sale_date desc
        limit 1) as last_amount
  from test

<四>、 recursive

<五>、lag() over() + min() over() / max() over()

  • 这个方法比较特殊化,不是所有场景都适用,主要针对一些有序的场景,比如上述例子针对日期amount都是有序的,可以将它当做一种思路
with tmp as (
	select product,
	       sale_date,
	       amount,
	       lag(amount) over (partition by product order by sale_date) as last_amount
	  from test
)
	select product,
	       sale_date,
	       amount,
	       coalesce(amount,max(amount)over(partition by product order by sale_date)) as last_amount
	  from tmp

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2249965.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ubuntu中使用ffmpeg和nginx推http hls视频流

视频流除了rtmp、rtsp&#xff0c;还有一种是http的hls流&#xff0c;使用http协议传输hls格式的视频数据。 nginx支持推送hls视频流&#xff0c;使用的是rtmp模块&#xff0c;即rtmp流推送成功了&#xff0c;hls流也没问题。怎么推送rtmp流&#xff0c;请参考我的文章&#x…

5.2.机器学习--岭回归+局部线性回归

目录 1.岭回归 1.1代码示例 2.局部线性回归 2.1代码示例 1.最小二乘法&#xff1a; 平面几何表达直线(两个系数): 重新命名变量: 强行加一个x01&#xff1a; 向量表达&#xff1a; 2.损失函数&#xff1a; 矩阵表达&#xff1a; 矩阵展开&#xff1a; 推导&#xff1a; …

nvidia-container-toolkit安装问题(OpenPGP)

1.正常情况下 apt-get install -y nvidia-container-toolkit2.使用nvidia源 nvidia-container-toolkit官网有安装教程 2.1 配置生产存储库 curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-containe…

电脑上的ip地址可以改吗?如何改变ip地址

在现代网络环境中&#xff0c;IP地址作为设备在网络中的唯一标识&#xff0c;扮演着至关重要的角色。无论是日常上网冲浪&#xff0c;还是进行专业的网络操作&#xff0c;IP地址都与我们息息相关。那么&#xff0c;电脑上的IP地址可以改吗&#xff1f;答案是肯定的。接下来&…

org.apache.log4j的日志记录级别和基础使用Demo

org.apache.log4j的日志记录级别和基础使用Demo&#xff0c;本次案例展示&#xff0c;使用是的maven项目&#xff0c;搭建的一个简单的爬虫案例。里面采用了大家熟悉的日志记录插件&#xff0c;log4j。来自apache公司的开源插件。 package com.qian.test;import org.apache.log…

PHP 生成分享海报

因为用户端有多个平台&#xff0c;如果做分享海报生成&#xff0c;需要三端都来做&#xff0c;工作量比较大。 所以这个艰巨的任务就光荣的交给后端了。经过一定时间的研究和调试&#xff0c;最终圆满完成了任务&#xff0c;生成分享海报图片实现笔记如下。 目录 准备字体文件…

ASP.NET Core 入门

使用 .NET CLI 创建并运行 ASP.NET Core Web 应用。 文章目录 一、先决条件二、创建Web应用项目三、运行应用四、编辑Razor页面 一、先决条件 .NET 8.0 SDK 二、创建Web应用项目 打开命令行界面&#xff0c;然后输入以下命令&#xff1a; dotnet new webapp --output aspne…

基于 Flask 和 Socket.IO 的 WebSocket 实时数据更新实现

简介 随着现代化应用的快速发展&#xff0c;实时数据交互已经成为许多 Web 应用的核心需求&#xff0c;比如实时消息推送、数据监控大屏等。本文将基于一个完整的 WebSocket 实现示例&#xff0c;带你一步步理解如何使用 Flask 和 Socket.IO 构建实时数据更新的 Web 应用。 将…

十、Spring Boot集成Spring Security之HTTP请求授权

文章目录 往期回顾&#xff1a;Spring Boot集成Spring Security专栏及各章节快捷入口前言一、HTTP请求授权工作原理二、HTTP请求授权配置1、添加用户权限2、配置ExceptionTranslationFilter自定义异常处理器3、HTTP请求授权配置 三、测试接口1、测试类2、测试 四、总结 往期回顾…

详细介绍HTTP与RPC:为什么有了HTTP,还需要RPC?

目录 一、HTTP 二、RPC 介绍 工作原理 核心功能 如何服务寻址 如何进行序列化和反序列化 如何网络传输 基于 TCP 协议的 RPC 调用 基于 HTTP 协议的 RPC 调用 实现方式 优点和缺点 使用场景 常见框架 示例 三、问题 问题一&#xff1a;是先有HTTP还是先有RPC&…

【Linux】 进程是什么

0. 什么是进程&#xff0c;为什么要有进程&#xff1f; 1.操作系统为了更好的管理我们的软硬件&#xff0c;抽象出了许多概念&#xff0c;其中比较有代表的就是进程了。通俗的来说操作系统为了更好的管理加载到内存的程序&#xff0c;故引入进程的概念。 2.在操作系统学科中用P…

[OpenHarmony5.0][Docker][环境]OpenHarmony5.0 Docker编译环境镜像下载以及使用方式

T. 已测试目录 主机类型主机版本Docker镜像版本结果WSL2Ubuntu22.04Ubuntu20.04PASSWSL2Ubuntu22.04Ubuntu18.04PASS R. 软硬件要求&#xff1a; 编译硬件需求&#xff1a;做多系统测试&#xff0c;磁盘500GB起步(固态)&#xff08;机械会卡死&#xff09;&#xff0c;内存3…

vue3-使用vite创建项目

vue-cli处于维护模式&#xff0c;也可以使用脚手架正常创建vue3项目&#xff0c;与vue2创建方式一致 官方推荐使用vite创建项目 vite 是新一代前端构建工具,官网地址轻量快速的热重载&#xff08;HMR&#xff09;&#xff0c;能实现极速的服务启动。对 TypeScript、JSX、CSS 等…

Java设计模式笔记(一)

Java设计模式笔记&#xff08;一&#xff09; &#xff08;23种设计模式由于篇幅较大分为两篇展示&#xff09; 一、设计模式介绍 1、设计模式的目的 让程序具有更好的&#xff1a; 代码重用性可读性可扩展性可靠性高内聚&#xff0c;低耦合 2、设计模式的七大原则 单一职…

Vue3+node.js实现登录

文章目录 前端代码实现后端代码实现跨域处理 前端代码实现 效果图 前端代码实现 <template><div class"login-container"><el-card class"login-card"><template #header><div class"card-header"><span>…

网络原理(一)—— http

什么是 http http 是一个应用层协议&#xff0c;全称为“超文本传输协议”。 http 自 1991 年诞生&#xff0c;目前已经发展为最主流使用的一种应用层协议。 HTTP 往往基于传输层的 TCP 协议实现的&#xff0c;例如 http1.0&#xff0c;http1.0&#xff0c;http2.0 http3 是…

Next.js-样式处理

#题引&#xff1a;我认为跟着官方文档学习不会走歪路 Next.js 支持多种为应用程序添加样式的方法&#xff0c;包括&#xff1a; CSS Modules&#xff1a;创建局部作用域的 CSS 类&#xff0c;避免命名冲突并提高可维护性。全局 CSS&#xff1a;使用简单&#xff0c;对于有传统…

navicat premium连接sqlserver

连接不上就双击安装图中的msi文件之后再连试试&#xff01;

Axure RP教程:创建高效用户界面和交互

Axure RP是一款广受好评的软件&#xff0c;专门用于设计精致的用户界面和交互体验。这款软件提供了众多UI控件&#xff0c;并根据它们的用途进行了分类。与此同时&#xff0c;国产的即时设计软件作为Axure的替代品&#xff0c;支持在线协作和直接在浏览器中使用&#xff0c;无需…

Qt导出Excel图表

目的 就是利用Qt导出Excel图表,如果直接画Excel 图表&#xff0c;比较麻烦些&#xff0c;代码写得也复杂了&#xff1b;而直接利用Excel模块就简单了&#xff0c;图表在模块当中已经是现成的了&#xff0c;Qt程序只更改数据就可以了&#xff0c;这篇文章就是记录一下利用模块上…