【问题标题】:Is there a SQL function to expand table?是否有扩展表的 SQL 函数?
【发布时间】:2020-04-01 01:48:36
【问题描述】:

我隐约记得有一个函数可以做到这一点,但我想我可能要疯了。

假设我有一个数据表,称之为 table1。它有三列:column1、column2、column3。查询

 SELECT * FROM table1 

返回 table1 中的所有行/列。是不是有某种类型的 EXPAND 函数可以让我复制该结果?例如,如果我想将 SELECT * FROM table1 查询中的所有内容复制三次,我可以执行 EXPAND(3) 之类的操作?

【问题讨论】:

  • CROSS JOIN 使用 3 行的计数表。

标签: sql google-bigquery


【解决方案1】:

如果你想要一个笛卡尔积(一行中的所有组合),你可以使用

SELECT a.*, b.*, c.* 
FROM table1 a
CROSS JOIN table1 b
CROSS JOIN table1 c

如果你想重复相同的行,你可以使用 UNION ALL

SELECT *
FROM table1 
UNION ALL 
SELECT *
FROM table1 
UNION ALL 
SELECT *
FROM table1 

【讨论】:

    【解决方案2】:

    全部使用联合

      Select * from table1
       Union all
       Select * from table1
        Union all
       Select * from table1
       Union all
       Select * from table1
    

    出于重用目的可以将此代码嵌入到procedure

       Create Procedure 
        expandTable(tablename 
         varchar2(50))
           As 
           Select * from table1
       Union all
       Select * from table1
        Union all
       Select * from table1
       Union all
       Select * from table1 
        End
        /
    

    【讨论】:

      【解决方案3】:

      在 BigQuery 中,我推荐CROSS JOIN

      SELECT t1.*
      FROM table1 CROSS JOIN
           (SELECT 1 as n UNION ALL SELECT 2 UNION ALL SELECT 3) n;
      

      这对于很多副本来说可能会很麻烦,但您可以通过生成数字来简化它:

      SELECT t1.*
      FROM table1 CROSS JOIN
           UNNEST(GENERATE_ARRAY(1, 3)) n
      

      这将创建一个包含三个元素的数组并将其取消嵌套到行中。

      在这两种情况下,您都可以在SELECT 中包含n 以区分副本。

      【讨论】:

        【解决方案4】:

        以下是 BigQuery 标准 SQL

        我认为下面的内容已经足够接近“让你发疯了”o)

        #standardSQL
        SELECT copy.*
        FROM `project.dataset.tabel1` t, UNNEST(FN.EXPAND(t, 3)) copy
        

        为此,您可以利用最近的announced 支持persistent standard SQL UDFs,即 - 您需要创建 FN.EXPAND() 函数,如下例所示(注意:您需要在您的项目 - 或使用现有数据集,在这种情况下您应该使用 YOUR_DATASET.EXPAND() 参考

        #standardSQL
        CREATE FUNCTION FN.EXPAND(s ANY TYPE, dups INT64) AS ( 
          ARRAY (
          SELECT s FROM UNNEST(GENERATE_ARRAY(1, dups)) 
          )
        ); 
        

        最后,如果您不想创建持久 UDF - 您可以使用临时 UDF,如下例所示

        #standardSQL
        CREATE TEMP FUNCTION EXPAND(s ANY TYPE, dups INT64) AS ( ARRAY(
          SELECT s FROM UNNEST(GENERATE_ARRAY(1, dups)) 
        )); 
        SELECT copy.*
        FROM `project.dataset.tabel1` t, UNNEST(EXPAND(t, 3)) copy
        

        【讨论】:

        • 这是一种更深入的高级方法,可以通过联合全部或笛卡尔积实现,如果确实需要,可以通过将笛卡尔或联合查询嵌入到过程(表名)中来构建自定义,并且可以需要时使用
        • 检查 stackoverflow.com/q/59305598/5221944 了解为什么/何时此版本非常有用 :o)
        猜你喜欢
        • 2013-11-09
        • 1970-01-01
        • 1970-01-01
        • 2010-11-03
        • 1970-01-01
        • 1970-01-01
        • 2018-05-29
        • 2014-11-27
        • 1970-01-01
        相关资源
        最近更新 更多