仅当存在多个行且在不同字段中具有给定值的行时,才更新记录集中的列?

时间:2014-10-31 20:21:12

标签: sql oracle

My_Table会是这样的:

user_id  shared_field  bool_field
-------  ------------  ----------
1        abc           null
2        def           null
3        ghi           Y
4        ghi           null
5        ghi           null
6        abc           Y
7        jkl           null

如果bool_field更改为与其他用户共享相同shared_field的用户(例如上面的user_id 3,4和5),则只有该用户应该具有“Y”。其余的应该在bool_field列中具有空值。例如,如果user_id 4现在应该具有'Y',我必须将user_id 4的bool_field更改为'Y',并确保user_id 3和5的bool_field值为null。

如果用户不与其他任何人共享shared_field值,则该bool_field应为null(如上面的user_id 1和2中所示)。

更新:添加了几行以显示多个user_id可以共享给定的shared_field(例如,1和6都有'abc'; 3,4和5都有'ghi' - 只有一个'abc'用户应该有'Y',只有一个'ghi'用户应该有'Y'等等,而其余用户的bool_field列中为null; user_ids不共享shared_field值,例如user_ids 2和7,它们的bool_field列中都应该为null。)清除为泥,对吧? ;)

此声明有效:

UPDATE my_table
   SET bool_field = (CASE
                       WHEN user_id = 4 THEN 'Y'
                       ELSE NULL
                      END)
 WHERE shared_field = 'ghi'
   AND (SELECT COUNT(shared_field)
          FROM my_table
         WHERE shared_field = 'ghi') > 1;

问题:在没有提前知道shared_field值的情况下,我是否可以通过某种方式完成同样的事情?例如(当然这不起作用) - 更新:“当然”意味着我知道这不起作用,因为它不是正确的Oracle语法!重点是要了解我正在尝试做什么。

UPDATE my_table
   SET bool_field = (CASE
                       WHEN user_id = 4 THEN 'Y'
                       ELSE NULL
                      END)
 WHERE shared_field = (SELECT shared_field FROM my_table WHERE user_id = 4) as sharedVal
   AND (SELECT COUNT(shared_field)
          FROM my_table
         WHERE shared_field = sharedVal) > 1;

更新:这是一个常规的SQL语句 - 我无法使用存储过程。

2 个答案:

答案 0 :(得分:1)

首先,告诉我们它是如何工作的,通常很有帮助,而不是说某些事情并没有起作用。例如,您发布的查询似乎有语法错误(as sharedVal无效,因为您无法为您在SELECT列表中计算的表达式分配别名。但是,不清楚是否"不起作用"意味着你得到语法错误(我们可以相对容易地使用错误消息进行调试)或者是否意味着查询运行但是没有做你想要的(我希望查询能做到这一点)语法错误已得到纠正)在这种情况下,了解查询如何做你想做的事情会有所帮助。

我希望像

这样的东西
UPDATE my_table a
   SET bool_field = (CASE WHEN user_id = 4 
                          THEN 'Y' 
                          ELSE NULL 
                      END)
 WHERE shared_field = (SELECT shared_field 
                         FROM my_table b
                        WHERE b.user_id = 4)
   AND EXISTS( SELECT 1
                 FROM my_table c
                WHERE a.shared_field = c.shared_field
                  AND a.user_id     != c.user_id )
假设user_id是主键,

开始工作。

答案 1 :(得分:0)

自从我使用Oracle以来已经有一段时间了,所以请检查以确保此查询返回您要更新的记录列表:

SELECT *
FROM my_table m
WHERE EXISTS (SELECT 1 
        FROM my_table 
        WHERE shared_field = m.shared_field 
        HAVING COUNT(shared_field) > 1);

如果是这样,那么这应该有效:

UPDATE my_table
   SET bool_field = (CASE
                       WHEN user_id = 4 THEN 'Y'
                       ELSE NULL
                      END)
WHERE EXISTS (SELECT 1 
        FROM my_table 
        WHERE shared_field = m.shared_field 
        HAVING COUNT(shared_field) > 1);

你也可以尝试这个WHERE条款:

WHERE shared_field IN (SELECT shared_field 
        FROM my_table 
        GROUP BY shared_field
        HAVING COUNT(shared_field) > 1);