【问题标题】:Convert list of values in SQL to CTE or Temp Table将 SQL 中的值列表转换为 CTE 或临时表
【发布时间】:2017-09-21 22:28:35
【问题描述】:

如何转换值列表,例如 (value1, value2, value3, ...., value500) 到临时表或 cte?

一种方法是:

WITH huge_list_cte AS (
   Select value1
   UNION
   Select value2 ...
)

有没有更好的办法?

【问题讨论】:

  • 值列表从何而来?你能创建一系列insert into #temp (field_name) values (value1) 语句吗?将这些值保存在数据库中后,您想如何处理它们?您的回答将有助于形成响应(CTE 与临时表)。
  • 您可以获得一个大字符串拆分函数(或在 SQL 2016 中使用 string_split),它接受一个字符串并根据分隔符值将其拆分为一个表。其中大多数允许将输出直接用作表格。
  • 您可以避免键入 500 select/union/column 进行动态查询。而且我不是在谈论查询的动态执行,而只是为了打印查询
  • 您可以手动创建一个临时表,并使用INSERT INTO ... Values(..),(...),(...)... 语句(注意:每个插入语句必须拆分为最多1000 行)。

标签: sql sql-server


【解决方案1】:

使用values:

WITH huge_list_cte AS (
      SELECT v
      FROM (VALUES (value1), (value2), . . . ) v(v)
     )
. . .

【讨论】:

  • 仅当值列表中的条目数为
  • 我可以不将每个值括在圆括号中吗?
  • @AnotherDeveloper 。 . .语法需要括号。
  • @GordonLinoff 明白了,谢谢。我的希望是,如果 SQL 引擎可以将 (a,b,c) 解释为值列表,那么将有一种方法可以获取 (a,b,c) 并​​直接从中选择,或者将其转换为另一个数据结构。
  • @AnotherDeveloper 。 . .列表不是 SQL 中的一种类型。它们实际上只是IN 表达式的一部分。 (许多数据库会将该构造解释为 tuple 而不是列表。)
【解决方案2】:

你可以使用table变量

DECLARE @Data TABLE(Id INT);
INSERT INTO @Data VALUES (101), (102) ...

然后你可以在你的查询中像普通表一样使用它

SELECT * FROM @Data

您甚至可以创建预定义的表类型并重复使用它Microsoft Docs: table

【讨论】:

    【解决方案3】:

    假设您有一个值列表 (value1, value2,...value500) 作为一个巨大的字符串.. 您可以先将其分配给变量,然后使用拆分列表类型的函数,然后将变量传递给函数。

    这就是你可以使用它的方式

    declare @input varchar(max) = ('value1,value2,value3,value499,value500')
    select * from dbo.SplitList (@input,',')
    

    我使用的函数是这样的:

    create FUNCTION [dbo].[SplitList](@String nvarchar(4000), @Delimiter char(1))
    RETURNS @Results TABLE (value nvarchar(4000))
    AS
    --this function takes two parameters; the first is the delimited string, the second is the delimiter
    
        BEGIN
        DECLARE @INDEX INT
        DECLARE @SLICE nvarchar(4000)
        -- HAVE TO SET TO 1 SO IT DOESNT EQUAL Z
        --     ERO FIRST TIME IN LOOP
        SELECT @INDEX = 1
    
        IF @String IS NULL RETURN
        WHILE @INDEX !=0
    
    
            BEGIN    
                -- GET THE INDEX OF THE FIRST OCCURENCE OF THE SPLIT CHARACTER
                SELECT @INDEX = CHARINDEX(@Delimiter,@STRING)
                -- NOW PUSH EVERYTHING TO THE LEFT OF IT INTO THE SLICE VARIABLE
                IF @INDEX !=0
                    SELECT @SLICE = LEFT(@STRING,@INDEX - 1)
                ELSE
                    SELECT @SLICE = @STRING
                -- PUT THE ITEM INTO THE RESULTS SET
                INSERT INTO @Results(value) VALUES(@SLICE)
                -- CHOP THE ITEM REMOVED OFF THE MAIN STRING
                SELECT @STRING = RIGHT(@STRING,LEN(@STRING) - @INDEX)
                -- BREAK OUT IF WE ARE DONE
                IF LEN(@STRING) = 0 BREAK
        END
    
        RETURN
    END
    

    这会返回一个包含所有值的表格。

    【讨论】:

      猜你喜欢
      • 2021-10-20
      • 2012-04-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-18
      • 1970-01-01
      • 2022-01-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多