如何从该选择语句PL / SQL进行更新

时间:2018-07-23 12:18:14

标签: sql oracle sql-update

我需要转换此选择:

select *
    from (select * from game where rownum <= 4 order by rownum desc)
  where rownum = 1;

进行更新,但我不知道我如何尝试过这样的事情

update game
   set x4 = 0
 where (select *
    from game
   where (select * from game where rownum <= 4 order by desc)
   where rownum = 1);

但是完全错误,我知道...在plsql中有任何想法或无法实现吗?

什么样的数据(这是一个例子):

    x1  x2  x3  x4  x5  x6
1   2   1   6   2   2   1
2   2   2   3   3   2   3
3   5   5   3   2   3   2
4   5   4   4   4   5   5
5   4   3   4   1   2   6
6   1   2   2   5   2   2

更新后我想要什么表(第4列和第4行更改为0):

    x1  x2  x3  x4  x5  x6
1   2   1   6   2   2   1
2   2   2   3   3   2   3
3   5   5   3   2   3   2
4   5   4   4   0   5   5
5   4   3   4   1   2   6
6   1   2   2   5   2   2
我试图使算法找到最佳的到达目的地的方法,重点是没有id,但总的来说,我认为我仍然需要添加它,因为无法在那些rownum上添加它。

3 个答案:

答案 0 :(得分:0)

在其中使用子查询时,必须将其结果分配给某些对象。 您的查询应如下所示。

update game g1
set x4 = 0
where g1.id in
(select g2.id
  from game g2
 where g2.id in
       (select * from (select g3.id from game g3 order by g3.id desc) g4 where rownum <= 4)
 and rownum = 1);

您需要先订购,然后才能使用rownum。

答案 1 :(得分:0)

您需要一个“键”(即其值明确标识单个记录的列[set];如果找不到,则最好重新访问数据模型)和记录的排序标准

假设您拥有这些内容,然后通过将它们编码为假设列idsort1来简化事情。

然后,您可以使用以下合并语句将前4个(根据您的排序标准)记录的x4列设置为0

   MERGE INTO game g
        USING (
                 SELECT * FROM (SELECT * FROM game gs order by gs.sort1 desc) WHERE rownum <= 4
              ) src
           ON (
                 src.id = g.id
              )
 WHEN MATCHED
         THEN UPDATE SET g.x4 = 0
            ; 

如果找不到“键”,则此解决方案可能会中断,因为更新可能包含不符合排序标准的记录。

如果您的排序标准不能区分前4名列表中的#4和#5项目,则查询之间的结果可能会有所不同(但无论如何,前4名都不会得到明确定义)

更新

如果只想更新一条记录,则可以对子查询使用简单的更新:

       UPDATE game g
          SET g.x4 = 0
        WHERE g.id = (
                  SELECT id FROM (SELECT * FROM game gs order by gs.sort1 desc) WHERE rownum = 4
              )
            ; 

演示

一个SQL小提琴,可以和here一起玩

答案 2 :(得分:0)

我想澄清一件事:您不需要ID,因为您需要更新密钥,即使在表上拥有一个密钥会更好,但是您需要使用一些东西来对行进行排序,不一定是钥匙。

不同地说,假设您的表上有一个ID,并基于该列具有PK,但是此ID是随机值;这对排序行和执行所需操作毫无用处。

您需要一些条件来对行进行排序,并确定哪一行是第四行。

假设表中有一个创建日期,则可以使用该日期对行进行排序,并使用rowid进行更新

create table tabTest(createDate, x1,  x2,  x3,  x4,  x5,  x6) as (      
    select date '2018-01-01', 2 ,  1 ,  6 ,  2 ,  2 ,  1 from dual union all
    select date '2018-01-02', 2 ,  2 ,  3 ,  3 ,  2 ,  3 from dual union all
    select date '2018-01-03', 5 ,  5 ,  3 ,  2 ,  3 ,  2 from dual union all
    select date '2018-01-04', 5 ,  4 ,  4 ,  4 ,  5 ,  5 from dual union all
    select date '2018-01-05', 4 ,  3 ,  4 ,  1 ,  2 ,  6 from dual union all
    select date '2018-01-06', 1 ,  2 ,  2 ,  5 ,  2 ,  2 from dual
)

您可以使用MERGE和分析函数进行排序:

merge into tabTest t
using (select rowid, row_number() over (order by createDate) as RN from tabTest) t2
on (t2.RN = 4 and t.rowid = t2.rowid)
when matched then
    update set x4 = 0

以相同的方式,您可以根据任何列或列的组合对行进行排序,但是您确实需要一种排序标准来说明哪一行是第四行。