10个SQL技巧之二:使用递归SQL生成数据

栏目: 数据库 · 发布时间: 7年前

内容简介:公用表表达式(也称为:CTE,如在Oracle中也称为子查询因子,)是在SQL中声明变量的唯一方法(除了只有PostgreSQL和Sybase SQL Anywhere支持得WINDOW模糊子句)。这是一个强大的概念。非常强大。请考虑以下声明:它产生了:

公用表表达式(也称为:CTE,如在Oracle中也称为子查询因子,)是在 SQL 中声明变量的唯一方法(除了只有PostgreSQL和Sybase SQL Anywhere支持得WINDOW模糊子句)。

这是一个强大的概念。非常强大。请考虑以下声明:

-- Table variables
WITH
  t1(v1, v2) AS (SELECT 1, 2),
  t2(w1, w2) AS (
    SELECT v1 * 2, v2 * 2
    FROM t1
  )
SELECT *
FROM t1, t2

它产生了:

v1 v2 w1 w2 
----------------- 
 1 2 2 4

使用简单的WITH子句,您可以指定表变量列表(记住:一切都是表),它们甚至可能相互依赖。

这很容易理解。这使得CTE(公用表格表达式)已经非常有用,但真正令人敬畏的是它们被允许递归!考虑以下PostgreSQL示例:

WITH RECURSIVE t(v) AS (
  SELECT 1     -- Seed Row
  UNION ALL
  SELECT v + 1 -- Recursion
  FROM t
)
SELECT v
FROM t
LIMIT 5

它产生了:

v 
- 
1 
2 
3 
4 
5

它是如何工作的?一旦你看到很多关键词,它就相对容易了。您定义一个公共表表达式,它只有两个UNION ALL子查询。

第一次UNION ALL个子查询是我通常所说的“种子行”。它“种子”(初始化)递归。它可以产生一行或几行,之后我们会递归。记住:一切都是一个表,所以我们的递归将发生在整个表上,而不是单个行/值。

第二次UNION ALL个子查询是递归发生的地方。仔细观察,你会发现它是从中选择的t。即允许第二个子查询从我们即将宣布的CTE中进行选择。递归。因此它也可以访问v列,它已经被使用它的CTE声明过的。

在我们的示例中,我们使用行播种递归(1),然后通过添加来递归v + 1。然后通过设置a LIMIT 5( 谨防可能无限的递归 - 就像 Java 8 Streams一样 )在使用现场停止 递归

附注:图灵完整性

递归CTE使SQL:1999图灵完成,这意味着任何程序都可以用SQL编写!(如果你够疯狂的话)

一个经常出现在博客上的令人印象深刻的例子:Mandelbrot Set,例如 http://explainextended.com/2013/12/31/happy-new-year-5/上 显示:

WITH RECURSIVE q(r, i, rx, ix, g) AS (
  SELECT r::DOUBLE PRECISION * 0.02, i::DOUBLE PRECISION * 0.02, 
        .0::DOUBLE PRECISION      , .0::DOUBLE PRECISION, 0
  FROM generate_series(-60, 20) r, generate_series(-50, 50) i
  UNION ALL
  SELECT r, i, CASE WHEN abs(rx * rx + ix * ix) <= 2 THEN rx * rx - ix * ix END + r, 
               CASE WHEN abs(rx * rx + ix * ix) <= 2 THEN 2 * rx * ix END + i, g + 1
  FROM q
  WHERE rx IS NOT NULL AND g < 99
)
SELECT array_to_string(array_agg(s ORDER BY r), '')
FROM (
  SELECT i, r, substring(' .:-=+*#%@', max(g) / 10 + 1, 1) s
  FROM q
  GROUP BY i, r
) q
GROUP BY i
ORDER BY i

在PostgreSQL上运行上面的内容,你会得到类似的东西:

                             ..:-....... = = * = :: - @@@@@ ::::。@ .. * - 。=。
                             ... = ... = ... :: +%@:@@@@@@@@@@@@@ + *#= =:+ - 。..-   
                             。:。:= :: * .... @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ..:。
                             ... * @@@@ = @:@@@@@@@@@@@@@@@@@@@@@@@@@@ = = ....:。...: :。
                              :: @@@@@: - @@@@@@@@@@@@@@@@@@@@@@@@@@@@:@ ..-:@ = * ::: 。
                              .- @@@@@ - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ = @@@@ = .. :
                              ... @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 。
                             ....: - * @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@: :   
                            ..... @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ..  
                          ..... @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - : ......   
                         .--:+。@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@ ...   
                         == @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@  -  ..   
                         .. + @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@ - #。  
                         ... = + @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@ .. 
                         - 。=  -  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@ ..:
                        。*%:@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@:@  - 
 。..:... ..- @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@ 
.............. ....- @@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%@ =
- = - .....-:。.......... :: @@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@ .. 
.. =:-.... = @ + .. = .... ..... @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@ :. 
:+ @@ :: @ == @ - *:%:+ .......:@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@。
:: @@@ - @@@@@@@@@ - := .....:@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@:
:@@@@@@@@@@@@@@@ =: .....%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@ 
:@@@@@@@@@@@@@@@@@ -...:@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@: - 
:@@@@@@ @@@@@@@@@@@@@ - ..%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@。
%@@@@@@@@@@@@@@@@@@@ -..- @@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@。
@@@@@@@@@@@@@@@@@@@@@ :: + @@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +
@@@@@@@@@@@@@@@@@@@@@@:@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@ .. 
@@@@@@@@@@@@@@@@@@@ @@@ - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@  - 
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@。 

令人印象深刻,是吧?


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Effective JavaScript

Effective JavaScript

David Herman / Addison-Wesley Professional / 2012-12-6 / USD 39.99

"It's uncommon to have a programming language wonk who can speak in such comfortable and friendly language as David does. His walk through the syntax and semantics of JavaScript is both charming and h......一起来看看 《Effective JavaScript》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

html转js在线工具
html转js在线工具

html转js在线工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具