Sql 根据条件按顺序更新列
我使用的是oracle 11g,我被困在这个问题上 我的表格结构如下 ╔═══════╦══════╦════════╗ ║ tm_id ║ flag ║ countr ║ ╠═══════╬══════╬════════╣ ║ 1 ║ 0 ║ null ║ ║ 2 ║ 0 ║ null ║ ║ 3 ║ 1 ║ null ║ ║ 4 ║ 0 ║ null ║ ╚═══════╩══════╩════════╝ Oracle 11g R2架构设置: 问题1: : 编辑-解释 这里使用SUM是一个聚合函数,而不是通常使用的聚合函数Sql 根据条件按顺序更新列,sql,oracle,oracle11g,Sql,Oracle,Oracle11g,我使用的是oracle 11g,我被困在这个问题上 我的表格结构如下 ╔═══════╦══════╦════════╗ ║ tm_id ║ flag ║ countr ║ ╠═══════╬══════╬════════╣ ║ 1 ║ 0 ║ null ║ ║ 2 ║ 0 ║ null ║ ║ 3 ║ 1 ║ null ║ ║ 4 ║ 0 ║ null ║ ╚═══════╩══════╩════════╝ Oracle
SUM( 1 - FLAG ) OVER ( ORDER BY tm_id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW )
几乎从右到左:
按tm_id排序-按tm_id升序对行排序
然后,对于每一行:
考虑无界的前一行和当前行之间的所有行,即仅从最早的tMyID开始到当前行的行。
对于这些行,查找SUM 1-标志,即当标志为零时递增计数器,而不是当标志为1时递增计数器。
Oracle 11g R2架构设置:
问题1:
:
编辑-解释
这里使用SUM是一个聚合函数,而不是通常使用的聚合函数
SUM( 1 - FLAG ) OVER ( ORDER BY tm_id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW )
几乎从右到左:
按tm_id排序-按tm_id升序对行排序
然后,对于每一行:
考虑无界的前一行和当前行之间的所有行,即仅从最早的tMyID开始到当前行的行。
对于这些行,查找SUM 1-标志,即当标志为零时递增计数器,而不是当标志为1时递增计数器。
要在更新中使用子查询:
如果您的表很大,您可能会发现合并效率更高。您希望在更新中使用子查询: 如果您的表很大,您可能会发现合并更有效。您应该使用游标。 从表中获取所有行。 根据案例条件逐个更新循环中的行。 在循环的最后一个declare变量中存储countr值。 如果flag=1,则在下一轮循环中使用此变量。您应该使用游标。 从表中获取所有行。 根据案例条件逐个更新循环中的行。 在循环的最后一个declare变量中存储countr值。
如果flag=1,则在下一轮循环中使用此变量。谢谢,这非常有效……我尝试用谷歌搜索你使用的东西,但你能给我一些上下文吗?我很难把它们放在一起,也无法理解你写的内容。@user1561770-添加了求和分析函数的解释。谢谢,这非常有效……我试着用谷歌搜索你使用的东西,但你能给我一些上下文吗?我很难将它们放在一起,也无法理解您所写的内容。@user1561770-添加的求和分析函数说明。
CREATE TABLE test ( tm_id, flag, countr ) AS
SELECT 1,0, CAST( NULL AS NUMBER ) FROM DUAL
UNION ALL SELECT 2,0, CAST( NULL AS NUMBER ) FROM DUAL
UNION ALL SELECT 3,1, CAST( NULL AS NUMBER ) FROM DUAL
UNION ALL SELECT 4,0, CAST( NULL AS NUMBER ) FROM DUAL
/
UPDATE test t
SET countr = ( SELECT total
FROM (
SELECT tm_id,
SUM( 1 - FLAG ) OVER ( ORDER BY tm_id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS total
FROM test
) x
WHERE t.tm_id = x.tm_id
)
/
SELECT * FROM test
| TM_ID | FLAG | COUNTR |
|-------|------|--------|
| 1 | 0 | 1 |
| 2 | 0 | 2 |
| 3 | 1 | 2 |
| 4 | 0 | 3 |
SUM( 1 - FLAG ) OVER ( ORDER BY tm_id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW )
update calendar t
set countr = (select count(*)
from calendar t2
where t2.tm_id <= t.tm_id and t2.flag = 0
);