sql—使用cte检索随机记录

8ljdwjyq  于 2021-07-26  发布在  Java
关注(0)|答案(2)|浏览(296)

我发现了下面的代码,工作正常。有没有人能建议一种方法,我可以把locations表集成到cte中,这样我就可以在每一行中获得一个随机的location\u 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;
col17t5w

col17t5w1#

以下是您想要的:

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;
wnrlj8wa

wnrlj8wa2#

从这个代码片段中很难知道发生了什么,但是如果您的目标是从具有数据的基表中以随机顺序使用数据来播种新表,则可以考虑生成随机值,然后按它们的行号排序,从而为自己提供一个伪主键(整数,递增):

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的随机顺序链接到地址”

相关问题