SQL 是一种声明式语言吗?

在学习SQL的时候,我们经常听到这样的说法:SQL是一种声明性语言。你只需要告诉它做什么,不用告诉它怎么做,它就会找到自己的实现方法。也就是说,你只需要用它来描述任务目标,而不需要解释计算过程,这与传统的过程语言有本质的区别。显然,这种编程语言听起来更容易学习和使用。 

真的有那么好吗?

让我们看一个例子。我们使用SQL来查询销售部门的女性员工人数。这是写好的SQL:

SELECT COUNT(*) FROM employee WHERE department='Sales' AND gender='Female'

看起来是这样的:我们不需要关心具体的计算过程(遍历employee表中的每一条记录,符合条件的则count加1,不符合则跳过,最后看count) ),只需说出要查询的目标即可。

我们再看一个例子:按部门查找30岁以上员工的平均工资:

SELECT department,AVERAGE(salary) FROM employee WHERE age>30 GROUP BY department

看起来也不错。在这里,我们真的不必关心如何分组和计算平均值。

虽然SQL仍然是一种语法严格的语言,但我们只有经过一定的学习才能写出正确的语句。不过,如果我们不关心计算过程的话,还是会省下不少功夫的。

让我们看另一个例子。确定贡献销售额前半部分的主要客户。如果我们设计计算过程的话,会是这样的:

  1. 计算所有客户的总销售收入。
  2. 按销售收入倒序对客户进行排序,大客户排在前,小客户排在最后。
  3. 按此顺序从0开始累加每个客户的销售收入,超过总销售收入的一半时停止。那么遍历到的客户就是目标客户。

那么,用 SQL 写出来是什么样的呢?这是我能想到的最简单的方法:

SELECT customer, amount, cum_amount
FROM ( SELECT customer,amount,SUM(amount) OVER (ORDER BY amount DESC) cum_amount FROM ordersummary )
WHERE cum_amount < (SELECT SUM(amount) FROM ordersummary)/2

仔细看看这条SQL语句,它基本上描述了上面的过程。有一个计算总销售额的子查询,后面跟着一个对销售额进行反向排序的子查询。窗口函数用于计算排序列表中每一行的累计销售额。然后主查询过滤掉累计销售额低于总销售额一半的客户。与上述过程唯一的区别是写入顺序。 SQL稍后开始计算总销售收入。还有一点逻辑上的差异,SQL的有序计算和逐步计算不好。在找到排名靠前的产品之前,有必要计算所有累计销售额。

这段SQL语句准确地描述了这样一个过程。描述任务目标而不担心计算过程怎么样?

举个更简单的例子:找到销售收入最高的前10名客户。

部分SQL语句写法如下: 

SELECT TOP 10 customer FROM ordersummary ORDER BY amount DESC

如果使用知名数据库,还需要使用子查询:

SELECT customer
FROM ( SELECT rownumber rn,customer FROM ordersummary ORDER BY amount DESC )
WHERE rn<=10

这两条SQL语句都清楚地告诉了我们计算过程:按照销售收入反向排序后,得到前10名。而且,在这个著名数据库的语法中,需要人为地创建一个序号,这意味着数据库需要更清楚地告诉如何计算。

如果我们看几百行SQL(存储过程),我们可以更清楚地看到,SQL仍然诚实地描述了计算过程,并且不同的计算过程可以带来截然不同的计算性能甚至结果。

事实上,任何编程语言在某种程度上都可以说是声明性语言:即它只需要关心目标而不需要关心过程。

如果用Java写程序,只需要关心变量如何变化,而不用关心CPU中寄存器的动作,但用汇编语言,就需要关心。同样,在使用汇编语言时,你需要关心寄存器的值,但不必担心与非门在CPU中如何运行。

在用SQL编写代码时,一般不需要担心变量和循环的具体动作。它没有变量的概念,但是有表、字段以及相关计算方法的概念,这个层面的流程也需要关注。从这个意义上来说,SQL和其他编程语言只是在描述问题上抽象层次不同,在解释过程上并没有本质区别。

为什么很多人认为SQL是一种所谓的声明式语言?这是因为SQL的设计刻意弱化了“过程性”特征,为了让语句更像英语,将基本操作放入了语句的每个子句中。当计算任务涉及的所有步骤都是SQL抽象层面内的基本操作时,可以将其写成一条语句,看似向SQL描述了任务目标。

然而,传统的编程语言通常不会将多个基本操作设计成一条语句的子句或函数参数,并提倡程序员将它们组合起来。这样,人们就会觉得有必要描述这个过程,而不具有“陈述性”的特征。

然而,语句的子句结构即使很复杂,也是有限的。当任务超出了这个结构的范围,需要使用嵌套子查询或中间结果来描述它时,SQL所谓的“声明式”假象就会暴露出来。还是有必要如实描述一下过程和方法。回顾一下前面的例子,就可以清楚地看出这一点。

在面对一些基本的查询任务时,SQL确实比Java等高级语言更容易学习和使用,但这并不是因为它比Java有更强的“声明性”特性,而是因为它在结构化数据计算方面具有更高的抽象层次比Java。

SQL刻意弱化了“过程性”特征,比如没有中间变量,这使得它描述过程的能力非常弱。当面对复杂的任务时,难度急剧增加,有些任务无法单独使用SQL来实现,因为没有过程化能力的SQL不是图灵完备的。所以,数据库厂商后来不得不补充和发明存储过程和CTE语法。

如果我们发明一种对数据计算具有高度抽象性同时保留其过程性特征的语言,你会发现它比 SQL 更容易学习和使用,尤其是在面对复杂的业务逻辑时。嗯,这就是集算器SPL。


作者:Judy Liu

更多技术干货请关注公号【云原生数据库

squids.cn,云数据库RDS,迁移工具DBMotion,云备份DBTwin等数据库生态工具。

irds.cn,多数据库管理平台(私有云)。

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

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

相关文章

搅拌站智能上料系统,无人值守,均匀布撒!

搅拌站中的骨料上料系统&#xff0c;遇上最新的人工智能技术&#xff0c;会碰撞出怎样的新发展和新突破&#xff1f;今天和砼行们分享一个现场案例&#xff0c;这是思伟软件在某数字化搅拌站中的应用。 上料无人值守 后场上料配合无人地磅系统&#xff0c;仅需1名操作员在控制…

[网络安全]在win2000虚拟机上创建隐藏账户

目录 1.winR->cmd->regedt32 2.新建账号&#xff0c;例如HiddenAccount$($表示在命令行下不现实此用户&#xff09; 3.winR->cmd->regedit 3.将HiddenAccount$删掉 4.最后一步 手工创建隐藏账户 1.你需要一台win2000 2.winR->cmd->regedt32 增加HEY_LOAC…

使用 Docker 部署企业培训系统 PlayEdu

1&#xff09;PlayEdu 介绍 官网&#xff1a;https://www.playedu.xyz/ GitHub&#xff1a;https://github.com/PlayEdu/PlayEdu PlayEdu 是一款适用于搭建内部培训平台的开源系统&#xff0c;旨在为企业/机构打造自己品牌的内部培训平台。PlayEdu 基于 Java MySQL 开发&…

zookeeper安装和启动

镜像下载地址&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/ 解压后将 conf 目录下的 zoo_sample.cfg 重命名为 zoo.cfg&#xff0c; 配置 admin.serverPort&#xff0c;防止跟 Tomcat 端口冲突 # 发送心跳的时间间隔 tickTime2000 # 集群中的follower服…

docker的应用和定义

Docker是一种开源的容器化平台&#xff0c;可以使用Docker容器来打包&#xff0c;分发和运行应用程序。它允许开发人员使用容器来将应用程序及其所有依赖项打包到一个可移植的容器中&#xff0c;使其可以在任何环境中运行&#xff0c;而不会受到环境差异或依赖问题的影响。 使…

python调取一欧易API并写一个比特币均线交易策略

比特币均线交易策略是一种基于比特币价格的移动均线的交易策略。它通过计算不同时间段的移动均线来确定买入和卖出点。 具体步骤如下&#xff1a; 确定要使用的均线。常用的均线包括5日、10日、20日、50日和200日均线。较短的均线可以更快地反应价格变动&#xff0c;而较长的均…

Android R修改wifi热点默认为隐藏热点以及禁止自动关闭热点

前言 Android R系统中WLAN 热点设置里面默认是没有wifi热点的隐藏设置选项的,如果默认wifi热点为隐藏热点可以修改代码实现。另外wifi热点设置选项里面有个自动关闭热点,这个选项默认是打开的,有些机器里面配置wifi热点后默认是需要关闭掉的,以免自动关闭后要手动打开。 …

实施之全网最最最详细安装系统,步骤清晰明了带图片(老毛桃ultraiso硬盘安装)

目录 一.老毛桃安装系统 1.1 制作启动U盘 1.2装机 二.ultraiso安装系统 2.1 制作启动U盘 2.2 装机 三、硬盘安装 一.老毛桃安装系统 1.1 制作启动U盘 1.1.1 准备 准备一个16G以上的U盘备份U盘重要文件&#xff0c;制作过程中会格式化U盘。本软件涉及对可移动磁盘的读写操作…

算法基础之欧拉函数

欧拉函数 核心思想&#xff1a;欧拉函数: 证明 &#xff1a;容斥原理 #include<iostream>#include<algorithm>using namespace std;const int N 110;int main(){int n;cin>>n;while(n--){int a;cin>>a;int res a;for(int i 2;i < a/i; i){if(a %…

Lammps错误:domain too large for neighbor bins

关注 M r . m a t e r i a l , \color{Violet} \rm Mr.material\ , Mr.material , 更 \color{red}{更} 更 多 \color{blue}{多} 多 精 \color{orange}{精} 精 彩 \color{green}{彩} 彩&#xff01; 主要专栏内容包括&#xff1a; †《LAMMPS小技巧》&#xff1a; ‾ \textbf…

智能优化算法应用:基于人工水母算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于人工水母算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于人工水母算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.人工水母算法4.实验参数设定5.算法结果6.…

uml网上选课系统 报告+mdl.zip

网上选课系统 一、实验目的 软件工程课程设计是软件工程专业一个综合性的实践教学环节&#xff0c;其目的在于促进学生复习和巩固计算机软件设计知识&#xff0c;加深对软件设计方法、软件设计技术和设计思想的理解&#xff0c;并能运用所学软件设计知识和面向对象技术进行综合…

redis 实现队列

一 使用场景 在一些场景&#xff0c;项目已发布了一段时间了&#xff0c;只是需要完善或优化一些功能要用到队列&#xff0c;但不想改动太大&#xff08;或者不想在安装第三方MQ组件框架&#xff09;的情况下可以用redis实现队列 。 二 redis实现队列 1 redis有序队列 使用red…

在打日志时,如何使用snowflake-id快速方便得随机获取query的唯一id

步骤一&#xff1a;安装snowflake-id pip install snowflake-id步骤二&#xff1a;代码示例 from snowflake import SnowflakeGeneratorgen SnowflakeGenerator(42)for i in range(100):val next(gen)print(val)参考文档&#xff1a; https://pypi.org/project/snowflake-…

Linux 命令行调试WiFi

参考&#xff1a; Linux&#xff1a;命令行调试WiFi&#xff08;iwlist/iwconfig/iw/wpa_supplicant/wpa_cli/dhcp/hostapd/hostapd_cli的使用方法&#xff09;-CSDN博客 iwlist wlan0 scan[ning] 列出WiFi扫描结果 iwlist wlan0 ap/accesspoint/peers 列出热点信息 iwl…

Scrum敏捷转型机构哪家好推荐

对于企业而言&#xff0c;敏捷转型是提升竞争力、适应市场变化的重要手段。为了实现这一目标&#xff0c;许多知名的培训公司提供了专业的敏捷培训课程和认证。其中&#xff0c;Leangoo领歌以其全面的敏捷研发管理解决方案和多种认证课程而备受认可。 1、Leangoo领歌&#xff…

CentOS6.10 卸载MySQL8.0.34升级至8.0.35

准备要更新的MySQL安装包,下载地址:MySQL :: Download MySQL Community Server 查看当前MySQL版本 备份数据库 mysqldump -uroot -p -B > /opt/backup/20231220_mysql.sql 检查备份文件 查看所有服务项: service --status-all 可以看到我们注册的MySQL服务是mysqld 停止…

Vue - 基于Element UI封装一个表格动态列组件

1 组件需求背景 在后台管理系统中&#xff0c;表格的使用频率非常高&#xff0c;统一封装表格动态列组件并全局注册使用&#xff0c;可大大提升代码的复用性和可维护性。 2 全局注册 src/plugins/index.js&#xff1a; import columns from ./columns/indexexport default …

el-date-picker日期时间插件只允许选择年月日小时并做可选择范围限制(精确到小时的范围)

一、首先明确下这个需求 1、要求只能选择年月日时,不要分钟和秒 2、根据后台返回的开始时间和天数设置可选择的开始时间和结束时间范围(包含小时)比如后台返回的开始时间是2023-12-20 13:24:30,天数365天,那么我们需要限制当前可选日期为2023-12-20 14时(不能选小于13:2…

嵌入式系统复习--ARM指令集(一)

文章目录 上一篇ARM指令集概述ARM寻址方式下一篇 上一篇 嵌入式系统复习–ARM技术概述 ARM指令集概述 ARM指令集是32位的&#xff0c;程序的启动都是从ARM指令集开始。 指令编码 第一操作数 第二操作数 目的操作数 条件影响标志位 不同功能实现的二进制位 指令编码 第…