2017-01-10 2 views
0

извините, если это уже было задано. я искал и не мог найти это конкретное решение. поэтому я был бы признателен за ответ или указатель на нужное место ... У меня есть две таблицы различной длины. Пример Игрушка:Как соединить большую таблицу T1 с меньшим T2 со случайными повторяющимися строками от T2

Т1:

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) 

Я хотел бы получить результат Т3, который присвоил случайные строки из 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 повторяется, потому что подзапрос выполняется только один раз

ответ

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; 
+0

Мне может понадобиться оптимизировать его позже для больших столов, пока мне это нужно, чтобы работать с примером игрушки, так что спасибо, он делает – Lizardie