【问题标题】:Using a cte to retrieve a random record使用 cte 检索随机记录
【发布时间】:2020-07-13 04:58:22
【问题描述】:

我找到了以下代码,它运行良好。有人可以建议一种方法如何将位置表集成到 cte 中,以便我每行都获得一个随机的 location_id。我怀疑我需要另一个联合,但我不确定如何获得随机 location_id

在此示例中,位置表是连续排序的,以便于发布,但并非总是如此。

 CREATE TABLE schedule_hdr AS
SELECT level AS schedule_id,
   'Schedule ' || level AS schedule_name

 FROM   dual
CONNECT BY level <= 2;

CREATE TABLE locations AS
 SELECT level AS location_id,
   'Door ' || level AS location_name,

CASE round(dbms_random.value(1,3)) 
        WHEN 1 THEN 'A' 
        WHEN 2 THEN 'T' 
        WHEN 3 THEN 'G' 
     END AS location_type

FROM   dual
CONNECT BY level <= 25;


 ALTER TABLE locations 
     ADD ( CONSTRAINT location_id_pk
   PRIMARY KEY (location_id));



WITH random_times (     schedule_id,    datetime, lvl ) AS (
 SELECT schedule_id,
      TRUNC(sysdate)
      + 
 NUMTODSINTERVAL( FLOOR(DBMS_RANDOM.VALUE(0,23*60)), 'MINUTE' ),
     1
FROM   schedule_hdr
 UNION ALL
SELECT schedule_id, 
     datetime + NUMTODSINTERVAL(FLOOR(DBMS_RANDOM.VALUE(6,11)), 'MINUTE'),
     lvl + 1
FROM   random_times
WHERE  lvl < 5
)
SELECT schedule_id,
   datetime
FROM   random_times
ORDER BY schedule_id, datetime;

【问题讨论】:

    标签: sql oracle random common-table-expression


    【解决方案1】:

    这就是你想要的:

    WITH random_times (     schedule_id,    datetime, lvl ) AS (
     SELECT schedule_id,
          TRUNC(sysdate)
          + 
     NUMTODSINTERVAL( FLOOR(DBMS_RANDOM.VALUE(0,23*60)), 'MINUTE' ),
         1
    FROM   schedule_hdr
     UNION ALL
    SELECT schedule_id, 
         datetime + NUMTODSINTERVAL(FLOOR(DBMS_RANDOM.VALUE(6,11)), 'MINUTE'),
         lvl + 1
    FROM   random_times
    WHERE  lvl < 5
    )
    SELECT
       schedule_id,
       datetime,
       loc.*
    FROM   random_times
          ,locations loc
    where loc.location_id = (
              select location_id
              from locations
              -- you need this predicate to disable subquery caching:
              where location_id*0 = schedule_id*0+lvl*0
              order by dbms_random.value()
              fetch first 1 row only
           )
    ORDER BY schedule_id, datetime;
    

    【讨论】:

    • 假设我有一个员工表(employee_id,emp_name)并且我希望一个随机的employee_id 与schedule_id 相关联,我应该只修改where 子句谓词吗?感谢您的时间、耐心和专业知识
    【解决方案2】:

    从这段代码 sn-p 中很难知道发生了什么,但如果您的目标是从有数据的基表中以随机顺序为新表播种数据,您可以考虑生成随机值,然后row_number 排序给自己一个伪主键(整数,递增):

    SELECT 
      t.*,
      row_number() over(order by dbms_random.value(1,10)) as pseudopk 
    FROM
      table
    

    例如,您有基本数据表(或 cte),例如:

    BasePerson
    Name, Age
    --------
    John, 20
    Mary, 30
    
    BaseAddress
    City
    ----
    New York
    Paris
    Berlin
    
    INSERT INTO RealAddress(ID, City)
    SELECT * FROM
    (
      SELECT row_number() over(order by dbms_random.value(1,10)) pk, a.City 
      FROM BaseAddress
    )
    WHERE pk < 3 --2 people need 2 address
    
    INSERT INTO RealPerson(ID, Name, Age, AddressID)
    SELECT pk, Name, Age, pk
    FROM(
      SELECT 
        row_number() over(order by dbms_random.value(1,10)) pk, 
        a.Name, 
        a.Age
      FROM BasePerson
    )
    

    我们对个人 ID 和他们的地址 ID 重复使用数字并不重要,因为地址数据在插入时是随机的,所以这是“相对于他们的 pk 的随机顺序的人,链接到地址相对于地址的pk随机排列"

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-28
      • 1970-01-01
      • 2021-12-26
      • 2022-09-25
      • 2023-03-16
      • 2017-10-04
      • 2015-01-20
      相关资源
      最近更新 更多