如何将较大的表T1连接到较小的T2,T2中随机重复行

时间:2017-01-10 10:07:29

标签: postgresql join random postgresql-9.3

抱歉,如果已经以某种方式询问过这个问题。我搜索过,找不到这个特定的解决方案。所以我会很感激答案或指向正确的地方...... 我有两张不同(不同)长度的桌子。玩具示例:

T1:

SELECT * FROM T1;
 gid | call_s1 
-----+---------
   1 |       1
   3 |       1
   4 |       1
   7 |       1
   8 |       1
(5 rows)

   SELECT * FROM T2;
     gid |       dt_ping       
    -----+---------------------
       1 | 2009-06-06 19:00:00
       2 | 2009-06-06 19:00:15
       3 | 2009-06-06 19:00:30
       4 | 2009-06-06 19:00:45
    (4 rows)

我想得到一个结果T3,如果有必要,已经将T2.dt_ping中的随机行分配给 T1中的每一行。例如,可能的结果是:

 gid | call_s1  | dt_ping
-----+----------+---------
   1 |       1  | 2009-06-06 19:00:45
   3 |       1  | 2009-06-06 19:00:30
   4 |       1  | 2009-06-06 19:00:15
   7 |       1  | 2009-06-06 19:00:00
   8 |       1  | 2009-06-06 19:00:45

我尝试过偏移,按随机排序等。要么我得到笛卡尔积或空值。例如,这是我的最后一次尝试:

SELECT
  T1.gid
  , T1.call_s1
  , T2.dt_ping
FROM
  (
    SELECT
      gid
      , call_s1
      , ceiling(  random() * (SELECT count(*)::int as n FROM fake_called_small )   )  tgid
    FROM fake_called_small
  ) T1
  LEFT OUTER JOIN
  fake_times_small T2
    ON
      T2.gid = T1.tgid;

我得到的结果之一:

 gid | call_s1 |       dt_ping       
-----+---------+---------------------
   1 |       1 | 
   3 |       1 | 2009-06-06 19:00:30
   4 |       1 | 2009-06-06 19:00:45
   7 |       1 | 2009-06-06 19:00:15
   8 |       1 | 
(5 rows)

我知道我错过了一些简单的东西,但又是什么?

是的,我试过这个:

SELECT
  T1.gid
  , T1.call_s1
  , (SELECT dt_ping FROM fake_times_small T2 ORDER BY random() LIMIT 1)
FROM fake_called_small  T1;

得到了:

 gid | call_s1 |       dt_ping       
-----+---------+---------------------
   1 |       1 | 2009-06-06 19:00:30
   3 |       1 | 2009-06-06 19:00:30
   4 |       1 | 2009-06-06 19:00:30
   7 |       1 | 2009-06-06 19:00:30
   8 |       1 | 2009-06-06 19:00:30
(5 rows)

重复dt_ping的同一行,因为子选择仅执行一次

1 个答案:

答案 0 :(得分:2)

如果您不关心性能,以下查询应该执行您想要的操作:

SELECT gid, call_s1, dt_ping
FROM (
  SELECT t1.gid, call_s1, dt_ping,
    ROW_NUMBER() OVER (PARTITION BY t1.gid, call_s1 ORDER BY RANDOM()) AS rn
  FROM t1
  CROSS JOIN t2
) x
WHERE rn = 1;