【问题标题】:How to update data by select random row value from another table如何通过从另一个表中选择随机行值来更新数据
【发布时间】:2019-12-19 01:35:23
【问题描述】:

我有三个表ABC,我想从表Bcol_b 列中随机取一行,然后更新到表A。表C是表B的子表,用于过滤表B的数据。 这是我的sql语句:

update a a
   set a.col_a_b =
       (select t.col_b
          from (select a1.col_a, b1.col_b, a1.rn_var
                  -- the number 6 is because I only have 6 rows of data,
                  -- and the real situation should be the total number of conditions in table b
                  from (select a0.col_a, TRUNC(dbms_random.value(1, 6)) rn_var 
                          from a a0) a1
                  left join (select b.col_b, rownum rn
                              from b b
                             where exists (select 1
                                      from c c
                                     where b.id = c.col_b_id
                                       and c.col_c = 'c1')) b1
                    on a1.rn_var = b1.rn) t
         where t.col_a = a.col_a);

我发现了一个奇怪的现象:

  • 如果我删除 a1.rn_varfrom (select a1.col_a, b1.col_b, a1.rn_var 行),它不会像我预期的那样工作

  • 在上面的基础上,如果我把exists换成left join(或者join),结果是一样的

  • 如果我同时删除 a1.rn_varexists,它会正常工作。

我知道可能有更好的方法来实现它,但谁能告诉我为什么?

更新:

其实是这个sql造成的:

select a1.col_a, b1.col_b -- remove a1.rn_var
  from (select a0.col_a, TRUNC(dbms_random.value(1, 6)) rn_var from a a0) a1
  left join (select b.col_b, rownum rn
               from b b
              where exists (select 1
                       from c c
                      where b.id = c.col_b_id
                        and c.col_c = 'c1')) b1
    on a1.rn_var = b1.rn
 -- this is for better display of results
 where a1.col_a = 'a1';

在上面的sql中,我可能会得到多行数据或者列b1.col_b为空,如下图:

a1  b1
a1  b2
a1  b4
------------------------------------------------
a1     -- here is null

另外,a1.col_a 列的每个值都是一样的,我的意思是,如果值a1 有多行,那么值a2(等等)的结果是一样的,像这样:

a1  b2
a1  b4
a1  b5
a2  b2
a2  b4
a2  b5
...

【问题讨论】:

    标签: oracle select random sql-update


    【解决方案1】:

    您可以使用随机数并按该随机数排序以获取随机记录。

    我更喜欢使用以下技术:

    UPDATE A A
    SET
        A.COL_A_B = (
            SELECT
                COL_B
            FROM
                (
                    SELECT
                        COL_B,
                        TRUNC(DBMS_RANDOM.VALUE(1, COUNT(1) OVER())) RANDOM_NUMBER  --GENERATES RANDOM NUMBER
                    FROM
                        (
                            SELECT DISTINCT
                                B.COL_B -- FETCHING DISTINCT RESULT
                            FROM
                                B B
                                -- EXISTS IS CONVERTED INTO JOIN
                                JOIN C C ON ( B.ID = C.COL_B_ID 
                                              AND C.COL_C = 'c1' )
                        )
                    ORDER BY
                        RANDOM_NUMBER -- ORDERING IS DONE BY RANDOM NUMBER
                    FETCH FIRST ROWS ONLY -- FETCHING ONLY FIRST ROW FROM ORDERED RECORDS
                )
        )
    

    干杯!!

    【讨论】:

    • 是的,这对我有用。如果你能告诉我我所描述的问题的原因,我会更高兴。
    • 首先,您的随机数 rn_var 只能包含 6 个数字,并且在您的情况下只选择表 b 中的前 6 个值。有关更多详细信息,您需要在删除问题中提到的列时告诉我实际结果是什么
    • 这是我的错,我已经更新了我的问题并添加了一些实际结果的示例。
    • 是的,分析了数据。这是因为您只使用了 6 个随机数,在我的示例中,我使用了表 b 的行数作为随机数。
    • 是的,你是对的。我的想法是我首先计算表b 中的行数,然后取随机数。这是错的吗?
    猜你喜欢
    • 2021-07-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-29
    • 2015-04-06
    • 1970-01-01
    • 2014-02-16
    • 2019-12-22
    • 1970-01-01
    相关资源
    最近更新 更多