【问题标题】:How to store a list of values as a variable to perform multiple SQL queries?如何将值列表存储为变量以执行多个 SQL 查询?
【发布时间】:2014-07-28 17:48:52
【问题描述】:

有没有办法将 WHERE 子句语句存储为可调用变量?

我需要使用不同的“日期”和“ID”值运行大约 20 次以下查询,但“代码”值将保持不变。但是,在 20 次查询之后,我需要将“代码”值更改为另一组值并使用相同的 20 个“日期”和“ID”组合。

我正在使用 SQL Server Management Studio 2012。

编辑:这实际上是一个子查询,我可以计算由此产生的记录数。每个计数查询都与其他计数查询联合,因此我可以一次执行所有查询并让结果显示 1 列的计数。我想知道如何制作一个包含每列特定于“代码”集的结果的 excel 表,但我还没有研究过。

SELECT DISTINCT a,b,c
    FROM mytable
    WHERE     (Code BETWEEN '201' AND '205') OR (Code BETWEEN '211' AND '215') OR (Code BETWEEN '241' AND '245') OR (Code = '450')
          OR  (Code BETWEEN '381' AND '387') OR (Code BETWEEN '391' AND '397') OR (Code BETWEEN '401' AND '420') OR (Code BETWEEN '441' AND '444') 
          OR  (Code BETWEEN '358' AND '360') OR (Code BETWEEN '371' AND '937') OR (Code = '499')                 OR (Code BETWEEN '218' AND '239'))
         AND  (Date > '20101231' AND Date < '20120101')
         AND  (ID IN ('3','6','7'))

我的代码值如何变化:

WHERE   (Code IN ('791','792'))
     OR (Code BETWEEN '801' AND '899')
     OR (Code BETWEEN '101' AND '125')
     OR (Code BETWEEN '401' AND '429')


WHERE   (Code BETWEEN '281' AND '749') OR Code = '2037'

还有另外2个代码列表,共5个,涉及BETWEEN、IN和=语句。如果有帮助,我也可以发布这些,但它们遵循与上述相同的声明方式。

日期值适用于日历年或季度。 ID 值通过 IN、NOT IN 或 = 表示。它们都是 char、varchar、tinyint 或 date。

替代方案:我可以一遍又一遍地复制和粘贴代码,但我想提高我的编码能力。此外,查找和替换仅读取单行。我无法让它适用于多行,例如 WHERE 子句。我听说过正则表达式,但不知道如何使用它们来做我想做的事。

感谢您的帮助!

【问题讨论】:

  • 为了我们的理解和更清楚,您能否提供您必须运行的两个不同的查询...我们看到上面的一个,您能否也证明另一个,以便我们更好地理解什么正在发生变化以及如何变化
  • SQL Server 中的“列表”或“数组”总是..... TABLE!这就是 SQL Server 的“多值”概念。因此,将您的值放入表中(临时表、表变量、表值参数),然后使用适当的 T-SQL 连接来获得您需要的内容。 不要重新发明轮子 - 它已经被发明了太多次......
  • 感谢marc_s的解释!

标签: sql sql-server sql-server-2012 table-variable


【解决方案1】:

如果这是一个临时查询,您只需要手动运行几次,这很丑陋但正确。

如果这是您经常做的事情,您可以将您的值存储在另一个表中。你可以有一个名为“coderange”的表,它有两列,“minCode”和“maxCode”。然后你会重写这个查询:

SELECT DISTINCT a,b,c
    FROM mytable m
      JOIN coderange c
    WHERE  Code Between c.minCode and c.maxCode
     AND  Date > '20101231' 
     AND Date < '20120101'
     AND  ID IN ('3','6','7');

【讨论】:

    【解决方案2】:

    我可能会创建一个参数化的存储过程,然后用正确的值反复调用它。

    一些链接:

    其他一些选择是使用动态 SQL 或创建一个基本的 .NET 包装器来创建您需要的查询并执行它。

    【讨论】:

    • 感谢您的链接。上个月我刚刚开始使用 SQL,这些将派上用场。
    【解决方案3】:

    在这种情况下,我将使用一个变量表来存储代码值,如下所示

    这里的@t表是变量表,即内存表,但也可以是永久表

    该表包含一个名为 key 的值,key 列将包含您要存储的每组代码范围的整数。

    对于下面的示例,我输入了一组值 1 和 2。

    declare @t TABLE 
    (
    key INT, FROM_code VARCHAR(10), TO_CODE VARCHAR(10)
    )
    
    
    insert into @T VALUES (1,'791','792')
    insert into @T VALUES (1,'801','899')
    insert into @T VALUES (1,'101','125')
    insert into @T VALUES (1,'401','429')
    
    Insert into @t values (2,'281','749')
    Insert into @t values (2,'2037','2037')
    

    现在,在 where select 语句中可以写成如下

    Declare @KEY INT
    -- PASS key as input parameter to the stored procedure.
    Set @key =1
    
    
    SELECT distinct a,b,c
    From <my_table> M
    JOIN @T T
    ON T.key = @key
    WHERE m.code between from_code and to_code
    

    对于第二次迭代,只需将 @key=1 替换为 @key=2

    【讨论】:

    • 这是一个我每次都需要声明的临时表吗?我没有说,但这是我的偏好。如果它存储在服务器上,我只需要由 DBA 人员运行它。
    • 如果这些值是永久的并且不经常更改,那么请务必将我的变量表 (@T) 更改为永久表(T 或某个名称)。
    • 这对我来说很新,所以我不知道如何让它在我的最后发挥作用。我得到“关键字'key'附近的语法不正确”,我认为这意味着我需要用可以将我正在查询的表(它实际上是一个视图)与@T链接的东西替换它。但是,我不确定这是如何工作的。为什么每个范围的第一个值都是 1?
    • 已编辑添加解释,如果您需要更多解释,请告诉我
    • 终于搞定了!谢谢!原来这个词 key 在 SMSS 中是保留的,所以我一直收到错误“关键字'key'附近的语法不正确”。我将键 INT 更改为 akey INT,将 T.key 更改为 T.akey,它现在可以工作了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多