Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从SQL表中的数字开始连续更新值_Sql_Oracle_Sql Update - Fatal编程技术网

从SQL表中的数字开始连续更新值

从SQL表中的数字开始连续更新值,sql,oracle,sql-update,Sql,Oracle,Sql Update,我有一个关于UPDATE语句用法的问题。有没有一种方法可以让我只用SQL编写以下场景,而不是编写存储过程 我试图简化这个案子 myTable有4列,其值如下: COMP1 COMP2 NO ACTIVE 0 0 4 N 4 1 Y 2 2 21 Y 3 1 1 Y 1 3 43 Y 2 1 Y 3 1

我有一个关于
UPDATE
语句用法的问题。有没有一种方法可以让我只用SQL编写以下场景,而不是编写存储过程

我试图简化这个案子

myTable
有4列,其值如下:

COMP1   COMP2   NO  ACTIVE
0       0       4   N
4       1           Y
2       2       21  Y
3       1       1   Y
1       3       43  Y
2       1           Y
3       1       12  Y
2       2       0   Y
3       2           Y
1       1       5   N
  • 我想选择值
    WHERE ACTIVE='Y'
    并开始更新 通过按
    COMP1、COMP2 ASC
    对其进行排序,它们的值不在任何列中
  • 编号必须从表
    中的
    MAX(NO)
    值开始,其中ACTIVE='N'

  • 具有相同COMP1和COMP2的行将具有相同的NO值

  • (注释后更新)无列不总是空的。此列中存在错误值,需要通过更新查询进行更正

因此,在执行
UPDATE
语句之后,
myTable
将如下所示(如果我们订购的话)

我想知道我是否能够做到这一点,而不需要选择整个列表并在存储过程中循环游标

(更新:我已经编写了SP。一个简化版本如下。它可能有问题,因为我更改了所有名称并删除了许多条件。)


我正在使用Oracle 11g

我假设
NO
字段在
ACTIVE='Y'
时始终为空。如果是这种情况,则无论是否指定了
WHERE ACTIVE='N'
条件,MAX(NO)都将返回相同的值。有了这个假设,这个
UPDATE
语句应该可以实现这个目的

UPDATE myTable 
SET NO = (SELECT MAX(NO) FROM myTable) + 1
WHERE ROWID IN 
(SELECT ROWID FROM myTable
WHERE ACTIVE = 'Y'
ORDER BY COMP1, COMP2);

可以使用窗口函数检索新号码:

下面将检索活动行并计算
no

select comp1, 
       comp2,
       row_number() over (order by comp1, comp2) + (select max(no) from mytable where active = 'N') as rn
from mytable
where active = 'Y'
现在可以在
MERGE
语句中使用它来对表运行更新。由于该表显然没有主键,我将使用
ROWID
匹配行:

merge into mytable tg
using (
    select rowid as rid,
           comp1, 
           comp2,
           row_number() over (order by comp1, comp2) + (select max(no) from mytable where active = 'N') as rn
    from mytable
    where active = 'Y'
) t on (t.rid = tg.rowid)
when matched then update
   set no = t.rn;

这肯定比使用单行更新的循环要快,尤其是对于较大的表

谢谢你的回答。但活动列为“Y”的字段中没有错误的值,即它们并不总是空的。Update语句必须更正这些值,并将正确的数字设置为NO列(我在问题中添加了这个)。我也试过你的例子,但它给出了ORA-00934错误,不允许我使用组函数。我编辑以消除错误。仍然不适合你,但我不想把坏代码留在这里。谢谢你。除了COMP1=COMP2的情况外,它几乎解决了这个问题。我也在尝试,但是您知道如何为具有与我的示例中相同的COMP1和COMP2的行设置相同的NO吗。我想,我们需要在行号()行写一个案例或类似的东西。@YigitalpErtem:
comp1=comp2
的问题可以通过使用
densite\u rank()
而不是
row\u number()
来解决。非常感谢。我需要学习分析函数,它们看起来很强大。
select comp1, 
       comp2,
       row_number() over (order by comp1, comp2) + (select max(no) from mytable where active = 'N') as rn
from mytable
where active = 'Y'
merge into mytable tg
using (
    select rowid as rid,
           comp1, 
           comp2,
           row_number() over (order by comp1, comp2) + (select max(no) from mytable where active = 'N') as rn
    from mytable
    where active = 'Y'
) t on (t.rid = tg.rowid)
when matched then update
   set no = t.rn;