【问题标题】:How to use a set of strings in a WHERE statement of SQL?如何在 SQL 的 WHERE 语句中使用一组字符串?
【发布时间】:2013-10-29 14:59:01
【问题描述】:

抱歉,我不知道如何为这个问题命名。我想在 sql 中选择一些记录,其中特定列是一组字符串。

示例。我有一个表学生,并有列 ID 和名称。 ID 有记录 1,2,3,4,5,6 。名称有 A、B、C、D、E、F。

我想返回 C,D,E WHERE ID=[3,4,5]。

我试过了

SELECT FROM student WHERE ID=2,3,4

它给出错误 ID=2,3,4 ='2,3,4' 并将 ID 作为单个列读取。我很迷惑。

在我的例子中,ID 集在存储过程变量中返回。这就像@ID

SELECT * FROM STUDENT WHERE ID=@ID 

上面的@ID 是一个字符串类型的变量,它保存着集合 {1,2,3}。请提供任何帮助。

【问题讨论】:

  • WHERE ID=[3,4,5] 这不是有效的语法。你想要WHERE ID IN (3, 4, 5),不幸的是你不能在那里添加一个包含合法值集的参数。您最好的选择是动态构造 SQL,或者将值插入临时表并执行连接(或在 IN 子句中进行子选择)。
  • 试试SELECT FROM student WHERE ID IN (2,3,4)

标签: c# sql-server sql-server-2008 select


【解决方案1】:

试试这个:

SELECT * FROM student WHERE ID IN (2,3,4)

语法:

test_expression IN 
    ( subquery | expression [ ,...n ]
    ) 

详细了解 IN 运算符here

【讨论】:

    【解决方案2】:

    WHERE ID=2,3,4WHERE ID='2,3,4' 是无效的 SQL 语法。

    看起来你可以根据你的情况使用IN (Transact-SQL)

    确定指定值是否与子查询中的任何值匹配 或列表。

    SELECT FROM student WHERE ID IN (2, 3, 4)
    

    你也可以看看杰夫的问题Parameterize an SQL IN clause

    【讨论】:

      【解决方案3】:

      如果您将 @ID 作为变量传递,并使用逗号分隔的 id 列表,WHERE IN (@ID) 将不起作用。

      我认为最好的办法是使用Table Valued function 先拆分它们,然后查询表。请在此处查看 Split() function

      用法:

      SELECT * FROM STUDENT 
      WHERE ID IN (
                    SELECT items FROM dbo.Split(@ID, ',') --Split function here
                  )
      

      【讨论】:

      • 这是一个简单的函数在这里的用途是什么请查看“Select Username from Student where ID IN ' + '('+ @Id +')'” where @Id=2 ,3,4 我们可以这样使用
      • @Anjali:OP 正在使用存储过程并且不传递内联 sql,因此除非您运行动态查询,否则它将无法工作。
      • 好的,但它适用于存储过程,我也在存储过程中使用该查询
      • 你能在此基础上帮助我吗?请来聊天
      • @Anjali:没问题,你可以邀请我。
      【解决方案4】:

      如果你想在Select中拟合多个值,你应该使用“in()”:

      SELECT * FROM student WHERE ID in (2,3,4)
      OR
      SELECT * FROM student WHERE ID between 2 and 4
      OR
      SELECT * FROM student WHERE ID = 2  OR ID = 3 OR ID = 4 
      

      在这种情况下,取第一个。 最后一个非常慢,不建议在这种情况下使用。

      【讨论】:

        【解决方案5】:

        请检查一下

        Select * from Student where Id IN ('2','3','4')
        

        看看这个

        Select Username from Student where ID IN ' + '('+ @Id +')'
         where @Id=2,3,4
        

        【讨论】:

        • 我知道给出的解决方案应该可以解决我的问题,但我的 ID 列是 bigINT 数据类型,当我尝试连接两个 i 时,我的 @id 变量返回为 {1,2,3}意思是 SELECT * FROM students where ID IN @ID 我得到错误,因为列 ID 是 BIGINT 并且我无法将 @ID 转换为 INT 请我该怎么做?你在吗?
        【解决方案6】:
        Select * from Student where Id='2'
        union all
        Select * from Student where Id='3'
        union all
        Select * from Student where Id='4'
        

        【讨论】:

          【解决方案7】:

          根据您在下面的评论,您不想将 ID 转换为 int。相反,使用LIKE 进行比较:

          SELECT * from STUDENT
          WHERE ', '+@ID+', ' LIKE ', '+CAST(ID as NVARCHAR(255)) + ', ';
          

          但是,查询不会被索引。如果您希望查询被索引,则使用动态 SQL:

          DECLARE @query NVARCHAR(max) = 'SELECT * FROM STUDENT WHERE ID IN ('+ @ID +')';
          EXEC sp_executesql @query;
          

          【讨论】:

          • 我知道给出的解决方案应该可以解决我的问题,但是我的 ID 列是 bigINT 数据类型,当我尝试连接两个 i 时,我的 @id 变量以 {1,2,3} 之类的字符串形式返回意思是 SELECT * FROM students where ID IN @ID 我得到错误,因为列 ID 是 BIGINT 并且我无法将 @ID 转换为 INT 请我该怎么做?你在吗?
          【解决方案8】:

          由于您使用的是存储过程,它也只有相等比较,即 id = 1,因此您也可以通过用逗号分隔值拆分输入来执行三个查询。

          或者您可以使用 SQL 向服务器添加具有自定义函数的新过程

          CREATE FUNCTION dbo.myparameter_to_list (@parameter VARCHAR(500)) returns @myOutput TABLE (mytempVal VARCHAR(40))
          AS  
          begin
               DECLARE @TempTable table
                    (
                    mytempVal VARCHAR(40)
                    )
          
               DECLARE @MySplittedValue varchar(40), @PositionOfComma int
          
               SET @par = LTRIM(RTRIM(@parameter))+ ','
               SET @PositionOfComma = CHARINDEX(',', @parameter, 1)
          
               IF REPLACE(@parameter, ',', '') <> ''
               BEGIN
                    WHILE @PositionOfComma > 0
                    BEGIN
                         SET @MySplittedValue = LTRIM(RTRIM(LEFT(@par, @PositionOfComma - 1)))
                         IF @MySplittedValue <> ''
                         BEGIN
                              INSERT INTO @TempTable (mytempVal) VALUES (@MySplittedValue) --Use conversion if needed
                         END
                         SET @par = RIGHT(@par, LEN(@par) - @PositionOfComma)
                         SET @PositionOfComma = CHARINDEX(',', @par, 1)
          
                    END
               END    
               INSERT @myOutput
               SELECT mytempVal 
                  FROM @TempTable
               RETURN
          END       
          

          在您的存储过程中,您可以这样使用它:

          Create Procedure StudentSelectFromSet 
          @Ids VARCHAR(MAX)
          AS
          SELECT * FROM student Stud
          WHERE Stud.Id IN(SELECT value FROM dbo.myparameter_to_list (@Ids))
          

          然后像之前访问的那样执行这个新过程。

          【讨论】:

          • 我知道给出的解决方案应该可以解决我的问题,但我的 ID 列是 bigINT 数据类型,当我尝试连接两个 i 时,我的 @id 变量返回为 {1,2,3}意思是 SELECT * FROM students where ID IN @ID 我得到错误,因为列 ID 是 BIGINT 并且我无法将 @ID 转换为 INT 请我该怎么做?你在吗?
          • @NuruSalihu 希望新编辑的答案为您的查询提供必要的解决方案
          猜你喜欢
          • 2019-03-19
          • 2011-11-07
          • 1970-01-01
          • 2014-12-17
          • 1970-01-01
          • 2011-12-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多