【问题标题】:Is it possible to use the SELECT INTO clause with UNION [ALL]?是否可以将 SELECT INTO 子句与 UNION [ALL] 一起使用?
【发布时间】:2010-10-10 03:14:16
【问题描述】:

在 SQL Server 中,这会将客户表中的 100 条记录插入到 tmpFerdeen 中:-

SELECT top(100)*
INTO tmpFerdeen
FROM Customers

是否可以跨 UNION ALL SELECT 执行 SELECT INTO :-

SELECT top(100)* 
FROM Customers
UNION All
SELECT top(100)* 
FROM CustomerEurope
UNION All
SELECT top(100)* 
FROM CustomerAsia
UNION All
SELECT top(100)* 
FROM CustomerAmericas

不太确定在哪里添加 INTO 子句。

【问题讨论】:

  • 你确定你需要联合所有吗?
  • 是的。因为记录在所有表中都是唯一的。

标签: sql sql-server


【解决方案1】:

我在解决方案中看到的挑战:

FROM( 
SELECT top(100) *
    FROM Customers 
UNION
    SELECT top(100) *  
    FROM CustomerEurope 
UNION 
    SELECT top(100) *  
    FROM CustomerAsia 
UNION
    SELECT top(100) *  
    FROM CustomerAmericas
)

这会创建一个将驻留在 RAM 中的窗口数据集,并且在更大的数据集上,此解决方案将产生严重的性能问题,因为它必须首先创建分区,然后它将使用该分区写入临时表。

更好的解决方案如下:

SELECT top(100)* into #tmpFerdeen
FROM Customers

Insert into #tmpFerdeen
SELECT top(100)* 
FROM CustomerEurope

Insert into #tmpFerdeen
SELECT top(100)* 
FROM CustomerAsia

Insert into #tmpFerdeen
SELECT top(100)* 
FROM CustomerAmericas

选择插入临时表,然后添加其他行。然而,这里的缺点是数据中是否有任何重复的行。

最佳解决方案如下:

Insert into #tmpFerdeen
SELECT top(100)* 
FROM Customers
UNION
SELECT top(100)* 
FROM CustomerEurope
UNION
SELECT top(100)* 
FROM CustomerAsia
UNION
SELECT top(100)* 
FROM CustomerAmericas

此方法适用于需要不同行的所有目的。但是,如果您想要重复的行只需将 UNION 替换为 UNION ALL

祝你好运!

【讨论】:

  • 请注意,使用UNION 获取不同的列表将对您的结果集进行“排序”。如果您要求它按照语句的顺序使用UNION ALL
  • 我不知道您所说的“窗口数据集”是什么意思。此查询不使用任何“窗口函数” - 当您使用 UNION 而不是 UNION ALL 时,您可能会在删除重复项(通过排序或散列)的计划中获得一个阻塞运算符,但这对于您的最终结果是相同的询问。将它放在派生表中不会让事情变得更糟。还要求SELECT ... INTO 创建一个新表。不是INSERT .. SELECT 现有的
【解决方案2】:

我会这样做:

SELECT top(100)* into #tmpFerdeen
FROM Customers

Insert into #tmpFerdeen
SELECT top(100)* 
FROM CustomerEurope

Insert into #tmpFerdeen
SELECT top(100)* 
FROM CustomerAsia

Insert into #tmpFerdeen
SELECT top(100)* 
FROM CustomerAmericas

【讨论】:

    【解决方案3】:

    对于 MS Access 查询,这很有效:

    SELECT * INTO tmpFerdeen FROM( 
        SELECT top(100) *
        FROM Customers 
    UNION All 
        SELECT top(100) *  
        FROM CustomerEurope 
    UNION All 
        SELECT top(100) *  
        FROM CustomerAsia 
    UNION All 
        SELECT top(100) *  
        FROM CustomerAmericas
    ) 
    

    这在 MS Access 中不起作用

    SELECT top(100) * 
      INTO tmpFerdeen
      FROM Customers
    UNION All
      SELECT top(100) * 
      FROM CustomerEurope
    UNION All
      SELECT top(100) * 
      FROM CustomerAsia
    UNION All
      SELECT top(100) * 
      FROM CustomerAmericas
    

    【讨论】:

      【解决方案4】:

      您根本不需要派生表。

      只需将INTO 放在第一个SELECT 之后

      SELECT top(100)* 
      INTO tmpFerdeen
      FROM Customers
      UNION All
      SELECT top(100)* 
      FROM CustomerEurope
      UNION All
      SELECT top(100)* 
      FROM CustomerAsia
      UNION All
      SELECT top(100)* 
      FROM CustomerAmericas
      

      【讨论】:

      • 我不同意 - 虽然上面的答案也是正确的,但接受的答案更明确
      【解决方案5】:
      SELECT * INTO tmpFerdeen FROM 
      (SELECT top(100)*  
      FROM Customers 
      UNION All 
      SELECT top(100)*  
      FROM CustomerEurope 
      UNION All 
      SELECT top(100)*  
      FROM CustomerAsia 
      UNION All 
      SELECT top(100)*  
      FROM CustomerAmericas) AS Blablabal
      

      这个“Blablabal”是必要的

      【讨论】:

        【解决方案6】:

        这适用于 SQL Server:

        SELECT * INTO tmpFerdeen FROM (
          SELECT top 100 * 
          FROM Customers
          UNION All
          SELECT top 100 * 
          FROM CustomerEurope
          UNION All
          SELECT top 100 * 
          FROM CustomerAsia
          UNION All
          SELECT top 100 * 
          FROM CustomerAmericas
        ) as tmp
        

        【讨论】:

        • 这也有效 SELECT top 100 * INTO tmpFerdeen FROM Customers UNION All SELECT top 100 * FROM CustomerEurope UNION All SELECT top 100 * FROM CustomerAsia UNION All SELECT top 100 * FROM CustomerAmericas(抱歉无法格式化这里是 sql)。谢谢!
        • “as tmp”的意义是什么?
        • @chrisVanOpstal,你为什么选择前 100 名?当我们选择所有记录时,它会给出错误-“ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效,除非还指定了 TOP 或 FOR XML。”。请给出一些解决方案。
        • 您好,关于@Dave 的提问,我看到删除“as tmp”会导致错误“期望为、id 或quoted_id 的语法不正确”。那么它是干什么用的呢?
        • @Dave, petric:在 SQL Server 中,临时表需要命名。就这样。除了使 SQL 语句有效之外,tmp 不提供任何其他功能。例如,在 Oracle SQL 上,这是可选的。
        【解决方案7】:

        也许试试这个?

        SELECT * INTO tmpFerdeen (
        SELECT top(100)* 
        FROM Customers
        UNION All
        SELECT top(100)* 
        FROM CustomerEurope
        UNION All
        SELECT top(100)* 
        FROM CustomerAsia
        UNION All
        SELECT top(100)* 
        FROM CustomerAmericas)
        

        【讨论】:

        • 缺少所需的表别名(如果添加将与接受的答案相同)
        【解决方案8】:

        尝试这样的事情:创建最终的对象表,tmpFerdeen 与联合的结构。

        然后

        INSERT INTO tmpFerdeen (
        SELECT top(100)* 
        FROM Customers
        UNION All
        SELECT top(100)* 
        FROM CustomerEurope
        UNION All
        SELECT top(100)* 
        FROM CustomerAsia
        UNION All
        SELECT top(100)* 
        FROM CustomerAmericas
        )
        

        【讨论】:

        • 在 SQL Server 中,临时表是动态创建的。我想在不创建最终对象表的情况下执行此操作。谢谢。
        猜你喜欢
        • 2015-09-01
        • 2021-10-30
        • 1970-01-01
        • 2016-05-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-20
        • 1970-01-01
        相关资源
        最近更新 更多