蓝色清爽网站,vs做的网站案例,个人网站建设课程,石林县工程建设个体交易网站在学习SQL的时候#xff0c;我们经常听到这样的说法#xff1a;SQL是一种声明性语言。你只需要告诉它做什么,不用告诉它怎么做#xff0c;它就会找到自己的实现方法。也就是说#xff0c;你只需要用它来描述任务目标#xff0c;而不需要解释计算过程#xff0c;这与传统的…在学习SQL的时候我们经常听到这样的说法SQL是一种声明性语言。你只需要告诉它做什么,不用告诉它怎么做它就会找到自己的实现方法。也就是说你只需要用它来描述任务目标而不需要解释计算过程这与传统的过程语言有本质的区别。显然这种编程语言听起来更容易学习和使用。  
真的有那么好吗 
让我们看一个例子。我们使用SQL来查询销售部门的女性员工人数。这是写好的SQL SELECT COUNT(*) FROM employee WHERE departmentSales AND genderFemale  看起来是这样的我们不需要关心具体的计算过程遍历employee表中的每一条记录符合条件的则count加1不符合则跳过最后看count 只需说出要查询的目标即可。 
我们再看一个例子按部门查找30岁以上员工的平均工资 SELECT department,AVERAGE(salary) FROM employee WHERE age30 GROUP BY department  看起来也不错。在这里我们真的不必关心如何分组和计算平均值。 
虽然SQL仍然是一种语法严格的语言但我们只有经过一定的学习才能写出正确的语句。不过如果我们不关心计算过程的话还是会省下不少功夫的。 
让我们看另一个例子。确定贡献销售额前半部分的主要客户。如果我们设计计算过程的话会是这样的 
计算所有客户的总销售收入。按销售收入倒序对客户进行排序大客户排在前小客户排在最后。按此顺序从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 rn10  这两条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多数据库管理平台私有云。