【问题标题】:SQL update where in set of dataSQL 更新数据集中的位置
【发布时间】:2012-07-22 11:09:00
【问题描述】:
+------------------+
| id1 | id2 | bool |
+------------------+
|  1  |  1  |  F   |
|  1  |  2  |  F   |
|  2  |  1  |  F   |
+------------------+

UPDATE table_name
SET bool = T
WHERE (id1, id2) IN ((1,1),(2,1)) --Need work here

所以基本上我想选择哪里的条件(id1,id2)=(value1,value2)。 类似于下面的语句:

WHERE id1 = value1 AND id2 = value2

但是在数组中的一组值中。 这可能吗?

提前致谢

编辑:我使用的是 SQL Server 2008。如果不太清楚,我很抱歉。 我试图把它作为一个存储过程并从服务中调用它。输入将是某种数组(可变大小),并在一行中找到两个 ID 的匹配项。

【问题讨论】:

    标签: sql arrays sql-server-2008 where


    【解决方案1】:

    这是在 MSSql 中执行此操作的方法。您只需从 Id1 和 Id2 生成一个值(在此示例中为 VARCHAR)。在这种情况下,您可以使用设置了值的 IN 语句。如果在这些字段中允许它们,您还应该考虑 id1 和 id2 中的 NULL(只需添加:and id1 is not null and id2 is not null)。

    UPDATE table_name
    SET bool = T
    WHERE convert(varchar(20),id1)+','+convert(varchar(20),id2) in ('1,1','2,1')
    

    【讨论】:

    • 非常感谢。这正是它。但是比较 varchar 实际上并不好,在性能方面,不是吗?
    • 其实你可以做任何类型的搜索值。例如,如果在您的表中说 id1,id2 始终
    【解决方案2】:

    实现这一点的一个想法是利用临时表

    Create Table #Temp
    (
      id1 int,
      id2 int
    )
    insert into #Temp values(1,1)
    insert into #Temp values(1,2)
    insert into #Temp values(2,1)
    insert into #Temp values(2,2)
    
    --update data
    UPDATE 
    table_name 
    SET bool = T 
    from table_name T1   
    inner join #Temp T2 
    on T1.Id1= T2.Id1
    and T1.Id2= T2.Id2
    

    【讨论】:

      【解决方案3】:

      试试这个 - SQL Server 2008 版本。

      create table mytable
      (
      id1 int,
      id2 int,
      bool char(1)
      );
      
      insert INTO mytable VALUES(1,1,'F');
      insert INTO mytable VALUES(1,2,'F');
      insert INTO mytable VALUES(2,1,'F');
      
      SELECT * FROM mytable;
      
      update mytable 
      set bool='T'
      WHERE exists (SELECT id1,id2 from mytable tb2
      where mytable.id1 = 1 AND mytable.id2 = 1
      or mytable.id1 = 2 AND mytable.id2 = 1);
      
      SELECT * from mytable;
      

      【讨论】:

        【解决方案4】:

        此查询在 oracle 中有效...

        UPDATE table_name 
        SET BOOL = T 
        WHERE (id1, id2) IN (SELECT 1,1 FROM DUAL UNION SELECT 2,1  FROM DUAL);
        

        你的数据库是什么?

        【讨论】:

        • 很抱歉我没有提供这些细节。我正在使用 SQL Server 2008
        • where 条件的输入数据类型是什么?我猜 Array 在 SQL Server 2008 中不存在。
        【解决方案5】:

        您从根本上想要做什么?为什么这是你选择这样做的方式?看来您对基于集合的逻辑的理解有点模糊。其他海报提供的每个答案都是有效的并且会起作用,但可能不是最适合您的目的。此处理是否针对现有数据集?它是数据加载或插入过程的一部分吗?您列出的每个 ID 字段都有自己的唯一值范围。根据您的示例,您似乎真正想要做的是在 ID2 = 1 时更新 bool 值

        UPDATE table_name SET Bool = 'T'
        WHERE Id2 = 1
        

        您更有可能想要开发一个基于某些数据规则设置 Bool 值的逻辑 - 例如,如果 Id2 小于或等于 Id1。案例陈述在这里起作用:

        UPDATE table_name SET Bool = CASE WHEN Id1 > Id2 THEN 'T' ELSE 'F' END
        

        当您处理大量数据时,这比在 WHERE 子句中为您插入的每个值的变体写入 AND/OR 规则要高效得多。

        将 WHERE 视为过滤器,而不是实现 if/then 类型逻辑的地方。

        在小型数据插入中(您可以手动在表格字段中键入值,或者从某种 Web 表单事务中逐个事务插入),最简单的方法可能是手动设置您认为合适的值,或者将其构建到系统的程序部分并将验证规则应用于表。

        如果您想编写一个执行此操作的存储过程,您可以为 ID 值创建变量,并将这些变量链接到将外部信息传输到数据库系统的任何系统。 (我假设您已经创建了表结构);

        CREATE PROCEDURE table_name_insert
        @Id1 Int NOT NULL,
        @Id2 Int NOT NULL
        
        -- If you want to execute the logic outside of the DB environment
        -- (perhaps as part of an SSIS package) then you will want to add this
        -- variable and pass it in explicitly.
        
        , @Bool bit NOT NULL 
        
        
        AS
        
        DECLARE @sql nvarchar(4000)
        
        
        SET @sql = '
        INSERT INTO table_name (ID1, ID2, Bool)
        SELECT @Id1, @Id2, [Case Logic or Variable Value for Bool]
        ' EXEC sp_executeSQL @sql
        

        您的程序可以调用此过程,并将可能从数组生成的变量传递给它。还有一些方法可以将值直接导入适当的列,然后在插入后代码中执行 Bool 逻辑。 “硬编码”一个 WHERE 语句来处理每种情况是低效的,而且是一个不好的习惯。

        【讨论】:

          【解决方案6】:

          如果你使用的是 SQL Server,试试这个

               UPDATE table_name
               SET bool = T
               WHERE (convert(varchar 20, id1) + '-' + convert(varchar 20 , id2)) 
                IN (convert(varchar 20 , value1) + '-' + convert(varchar 20 , value2),
                  convert(varchar 20 , value3) + '-' + convert(varchar 20 , value4));
          

          如果您正在使用 oracle,请尝试此操作

               UPDATE table_name
               SET bool = T
                 WHERE (id1 || '-' || id2) IN (value1 || '-' || value2)
          

          如果我们有多个要匹配的值,我们通常会使用 in 子句。 假设你 (id1 = value1 and id2 =value2) and (id1 = value3 and id2 =value4)

               UPDATE table_name
               SET bool = T
               WHERE (id1 || '-' || id2) IN (value1 || '-' || value2, value3 || '-' || value4)
          

          【讨论】:

          • 感谢您的回答。我确实在 SQL Server 上尝试过,它执行得很好。然而结果不是我想要的。它给出了有趣的结果,我不确定条件语句的作用。你愿意解释一下,也许适用于其他东西。谢谢
          • 我的代码更适合 oracle,因为我使用 oracle,我将编辑我的答案以使用 SQL server 再次解释它
          【解决方案7】:

          您可以将值列表作为 XML 发送到存储过程。将 XML 解压缩到表变量并使用 exists 查找应更新的行。

          create procedure YourSP
            @XMLParam xml
          as
          
          declare @T table(id1 int, id2 int)
          
          insert into @T(id1, id2)
          select T.N.value('id1[1]', 'int'),
                 T.N.value('id2[1]', 'int')
          from @XMLParam.nodes('/Row') as T(N)
          
          update table_name
          set bool = 'T'
          where exists (select *
                        from @T as T
                        where T.id1 = table_name.id1 and
                              T.id2 = table_name.id2)
          

          这样调用:

          exec YourSP '<Row>
                         <id1>1</id1>
                         <id2>1</id2>
                       </Row>
                       <Row>
                         <id1>2</id1>
                         <id2>1</id2>
                       </Row>'
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-06-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-08-22
            相关资源
            最近更新 更多