【问题标题】:SQL - how to create multi row results with no source tableSQL - 如何在没有源表的情况下创建多行结果
【发布时间】:2010-10-24 19:48:23
【问题描述】:

在标准SQL中,有没有办法说:

select mubmle as x from mumblemmble

并且得到不止一行的结果,像这样

 x
 _ 
 1
 2
 3

不创建临时表?如果我知道某个表有足够的行,我可以在 SQL Server 中使用 row_count() 来完成,例如:

  select row_number() over (order by x.SomeColumn) from 
(select top 24 SomeColumn from TableThatHasAtLeast24Rows) x

但想知道是否有标准(不那么愚蠢)的方法来做到这一点。

【问题讨论】:

    标签: sql


    【解决方案1】:

    没有标准的方法,MySQL 也没有。

    Oracle:

    SELECT  *
    FROM    dual
    CONNECT BY
            level < n
    

    MS SQL:

    WITH hier(row) AS
            (
            SELECT  1
            UNION ALL
            SELECT  row + 1
            FROM    hier
            WHERE   row < n
            )
    SELECT  *
    FROM    hier
    OPTION (MAXRECURSION 0)
    

    PostgreSQL:

    SELECT  *
    FROM    generate_series (1, n)
    

    请注意,MS SQLOracle 不同,它不能将递归堆栈交换到临时表空间,因此在生成大型数据集时可能会遇到麻烦。

    详情请见this answer

    【讨论】:

    • 对于 MS SQL,您可以使用选项 MAXRECURSION 将其从 5 月 32767 或无限 (0) 更改
    【解决方案2】:

    SQL 2003 标准定义了一种实现方式 - 但并非所有 DBMS 都实现它:

    <table value constructor> ::= VALUES <row value expression list>
    
    <row value expression list> ::= <table row value expression>
                                [ { <comma> <table row value expression> }... ]
    
    <row value expression> ::= 
             <row value special case>
         |   <explicit row value constructor>
    
    <table row value expression> ::= 
             <row value special case>
         |   <row value constructor>
    

    而且,在经历了许多其他 BNF 之后,您会发现:

    <explicit row value constructor> ::= 
             <left paren> <row value constructor element> <comma>
                          <row value constructor element list> <right paren>
         |   ROW <left paren> <row value constructor element list> <right paren>
         |   <row subquery>
    
    <row value constructor element list> ::= 
         <row value constructor element>
         [ { <comma> <row value constructor element> }... ]
    
    <row value constructor element> ::= <value expression>
    

    当翻译时,这意味着在某些情况下,您可以使用:

     VALUES (v1a, v1b, v1c), (v2a, v2b, v2c)
    

    创建一个表值,每行包含两行三列。 INSERT 语句是您可以使用该构造的一个地方。另一个是在 SELECT 语句的 FROM 子句中,尽管显示足够的 BNF 来连接点会占用比 SO 鼓励的答案更多的空间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-12
      • 2020-12-07
      • 1970-01-01
      • 2011-02-28
      • 2017-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多