【发布时间】:2017-01-24 08:06:05
【问题描述】:
我有一个如下所示的表格
ID | action | flag
1 | A | 1
1 | A | 1
1 | B | 1
2 | A | 1
2 | A | 1
2 | B | 1
2 | B | 1
我想要执行以下操作:如果对于相同的 ID,action 列中的值 B 出现的次数多于 1时间,那么我想将这个ID的flag列设置为0。
结果应该是这样的:
ID | action | flag
1 | A | 1
1 | A | 1
1 | B | 1
2 | A | 0
2 | A | 0
2 | B | 0
2 | B | 0
我知道两种方法:
- 使用子查询:但是我不想使用子查询,因为我处理的是大表,子查询会降低性能
- 使用临时查找表:我创建了一个临时查找表,其中存储了 action 中具有值 B 的 IDs列超过 1 次,然后我
join与原始表的临时表找到我将为其设置 flag 的 IDs到 0
除了上述两种方法之外,还有其他选择吗?理想情况下在一个查询中(没有子查询和临时查找表)。我在想JOIN 之类的东西,其中JOIN 子句包含GROUP BY 和HAVING 之类的东西,但直到现在我才成功..
【问题讨论】:
-
对于
ID=1,A也不止一次出现。为什么只需要更新ID=2? -
“子查询会降低性能” - 这句话并不总是正确的.....
-
因为条件是,
B应该出现多次。 -
@AndyKorneyev,但肯定比创建查找表一次更糟糕,因为子查询需要为每一行执行一次。
-
@beta “因为子查询需要为每一行执行一次。” - 这个语句并不总是正确的,例如像
update t set.... where ID in (subquery)这样的子查询(或查询in answers) 将只执行一次整个查询。
标签: sql-server join sql-update aggregate