为什么是或为什么不?
最佳答案
SQL
被设计为一种声明性语言,从某种意义上说,您告诉您想要获取的what
,而SQL
引擎决定了how
。
但是,SQL
对集合进行操作,并且函数的结果可以是Oracle
,SQL Server
和PostgreSQL
中的第一类集合。
可以说SQL
是函数语言,只要函数将集合作为其输入并产生一个集合作为其输出即可。
也就是说,您可以编写如下内容:
SELECT *
FROM mytable t
JOIN myfunction(x) f
ON f.col1 = t.col2
,甚至:
SELECT *
FROM mytable t
CROSS APPLY
myfunction(t.col2) f
(在
SQL Server
中)或这个:
SELECT t.*, myfunction(t.col2)
FROM mytable t
(在
PostgreSQL
中)但是,这不是
SQL
标准的一部分。就像
C++
编译器试图找到一种将两个float
相乘的最佳方式(就普通代数而言)一样,SQL
优化器试图寻找一种对两个集合进行相乘的最优方式(就关系代数而言)。在
C++
中,您只需编写a * b
并依靠编译器为此生成最佳程序集。在
SQL
中,您编写SELECT * FROM a NATURAL JOIN b
并依赖优化器。但是,使用所有
SQL
声明的声明性(无双关语),大多数真正的优化器只能执行非常基本的查询重写。说,据我所知,没有任何优化器能够对此查询使用相同的有效计划:
SELECT t1.id, t1.value, SUM(t2.value)
FROM mytable t1
JOIN mytable t2
ON t2.id <= t1.id
GROUP BY
t1.id, t1.value
为此:
SELECT id, value, SUM(t1.value) OVER (ORDER BY id)
FROM mytable
,更不用说更复杂的查询了。
这就是为什么您仍然需要制定查询条件,以便它们使用有效的计划(同时仍产生相同的结果),从而使
SQL
少了一种声明性语言。我最近在我的博客上发表了以下文章:
关于sql - 除了声明性语言之外,SQL是功能语言吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1153397/