sql 判断条件累加_SQL 是描述性语言?

SQL 是描述性语言?

14c1c16a061b2b6408a14415e4cd2335.png

我们在学习 SQL 时,常常会看到这样的论调:SQL 是一种描述性语言,你只需要告诉它要做什么,而不需要告诉它怎么做,它会自己找到实现方法。也就是说,你要只用它描述任务目标,而不需要说明计算过程,这和传统的过程式语言有本质的差别。

真是这样的吗?


试一个例子,我们用 SQL 来查询员工中中国男性的数量,写出来是这样:

SELECT COUNT(*) FROM 员工表 WHERE 国籍 =‘中国’ AND 性别 =‘男’

看起来是这样,我们不需要关心具体的计算过程(遍历员工表中每一条记录,碰到符合条件的则计数加 1,不符合条件者略过,最后看计数),只要说清要查询的目标就可以了。

再举一例,按部门统计女员工的平均工资:

SELECT 部门,AVERAGE(工资) FROM 员工表 WHERE 性别 =‘女’ GROUP BY 部门

也不错,在这里我们确实不必关心到底如何分组和计算平均。

尽管 SQL 仍然是一种严格语法,我们经过一定的学习才能写出正确的语句,但如果能不关心计算过程,那还是会省很多事的。


我们再看一个例子:找出销售额贡献度在前一半的大客户。如果设计一下计算过程,那么很容易想到这样的流程:

1. 计算所有客户的总销售额,记为 S

2. 把客户按销售倒排序,即大的在前小的在后

3. 按 2 的列表从 0 开始累加客户的销售额,超过 S/2 时停止,则已经遍历过后客户则是目标客户

那么,用 SQL 写出来是什么样的呢?

SELECT 客户, 销售额, 销售额累计

FROM (SELECT 客户, 销售额,SUM( 销售额) OVER (ORDER BY 销售额 DESC) 销售额累计 FROM 订单统计表 )

WHERE 2* 销售额累计 < (SELECT SUM( 销售额) FROM 订单统计表 )

仔细看一下这个 SQL(我没想出更简单的写法了),它几乎是在严格地描述上述过程,所不同的只是书写次序(SQL 把开始计算总销售额写在了后面),和微小的逻辑差异(要把所有的累计销售额计算出来,再找出前面的)。

说好的只要描述任务目标而不必关心计算过程呢?


再看简单一些的例子:查询销售额贡献最多的 10 名客户。

某些 SQL 写出来是这样:

SELECT TOP 10 客户 FROM 订单统计表 ORDER BY 销售额 DESC

如果用某著名数据库来做,还得用子查询:

SELECT 客户

FROM (SELECT rownumber rn, 客户 FROM 订单统计表 ORDER BY 销售额 DESC)

WHERE rn<=10

这两个 SQL 都明白无误地告诉我们计算过程:按销售额倒排序之后取前面 10 个。


如果再找个数百行的 SQL(存储过程)来看,则可以更清楚地看到 SQL 照样在解释计算过程,而且不同的计算过程还会带来截然不同的计算性能甚至计算结果。

其实。任何程序设计语言都可以说在某种程度下的描述性语言:只需要关心目标而不必关心过程。如用 Java 写程序,你只要关心变量如何变化,而不必关心 CPU 中寄存器的动作,但用汇编语言就要关心;同样,而用汇编语言时,虽然你要关心寄存器的取值,但却不必关心 CPU 里与非门是如何动作的;用 SQL 写代码时一般不用再关心变量、循环的具体动作,但要操心表、字段这些概念上的计算过程。SQL 和其它程序设计语言在描述问题的解决方法上只是抽象层次不同,对于过程的说明并没有任何本质的不同。前面那两个例子之所以让我们感觉 SQL 象是所谓描述性语言,只是因为情况非常简单,恰好只是 SQL 抽象层次内的基本运算。而 SQL 因为长得又很象英语,在简单情况时易读易写,更容易给人这种错觉。

SQL 是非常成功的程序语言,但说它是一种与众不同的描述性语言,却是一句鬼话。拿一些简单问题举例,能蒙骗住暂时没有深入思考的人。其实,只要把问题稍复杂化一点,这个说法就会露馅。可惜,很多人都不会去做哪怕一点点地深入求证,而只是人云亦云。SQL 不比其它语言有更多的“描述性”,这并不减少 SQL 的成功程度。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQL 中,可以使用条件语句来动态拼接查询条件。常见的条件语句有 `IF` 和 `CASE WHEN` 两种。 假设有一个学生表 `students`,其中有 `name`、`age`、`gender` 三个字段,现在要查询年龄大于等于 18 岁的男生或者年龄大于等于 20 岁的女生,可以通过以下 SQL 语句实现: ```sql SELECT * FROM students WHERE age >= CASE gender WHEN 'male' THEN 18 WHEN 'female' THEN 20 ELSE 0 END ``` 上述 SQL 语句中,`CASE WHEN` 语句判断传入的参数 `gender` 是男还是女,分别返回年龄限制条件 18 和 20,如果传入的参数不是男也不是女,则返回 0,这样就可以避免查询出不符合条件的数据。 如果使用的是编程语言,可以在程序中动态生成 SQL 语句,根据传入的参数拼接查询条件。例如,在 Python 中可以使用字符串拼接来生成 SQL 语句,如下所示: ```python def query_students(gender, age): sql = "SELECT * FROM students WHERE 1=1" if gender == 'male': sql += " AND gender='male' AND age >= 18" elif gender == 'female': sql += " AND gender='female' AND age >= 20" if age: sql += f" AND age <= {age}" return sql ``` 上述代码中,首先定义了一个 SQL 语句 `SELECT * FROM students WHERE 1=1`,这里的 `WHERE 1=1` 是为了方便拼接后续的查询条件。然后根据传入的参数 `gender` 和 `age`,动态拼接查询条件,最后返回完整的 SQL 语句。 注意,在拼接 SQL 语句时需要注意防止 SQL 注入攻击。建议使用参数化查询或者安全过滤来避免 SQL 注入。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值