Вернуть пять строк случайной ДНК вместо одной - PullRequest
1 голос
/ 01 мая 2020

Это код, который я должен создать строку ДНК:

prepare dna_length(int) as
  with t1 as (
    select chr(65) as s 
      union select chr(67) 
      union select chr(71) 
      union select chr(84) )
, t2 as ( select s, row_number() over() as rn from t1)
, t3 as ( select generate_series(1,$1) as i, round(random() * 4 + 0.5) as rn )
, t4 as ( select t2.s from t2 join t3 on (t2.rn=t3.rn))
select array_to_string(array(select s from t4),'') as dna;

execute dna_length(20);

Я пытаюсь выяснить, как переписать это, чтобы дать таблицу из 5 строк строк ДНК длины 20 каждый вместо одного ряда. Это для PostgreSQL.

Я пытался:

CREATE TABLE dna_table(g int, dna text);
INSERT INTO dna_table (1, execute dna_length(20));

Но, похоже, это не работает. Я абсолютный новичок. Как это сделать правильно?

Ответы [ 2 ]

0 голосов
/ 01 мая 2020

Это может быть намного проще и быстрее:

SELECT string_agg(CASE ceil(random() * 4)
                   WHEN 1 THEN 'A'
                   WHEN 2 THEN 'C'
                   WHEN 3 THEN 'T'
                   WHEN 4 THEN 'G'
                  END, '') AS dna
FROM   generate_series(1,100) g  -- 100 = 5 rows * 20 nucleotides
GROUP  BY g%5;

random () производит random value in the range 0.0 <= x < 1.0. Умножьте на 4 и возьмите математический потолок с помощью ceil () (дешевле, чем round()), и вы получите случайное распределение чисел 1-4. Преобразовать в ACTG и агрегировать с GROUP BY g%5 - %, являющимся оператором по модулю .

О string_agg():

Как подготовленный оператор, принимая
$1 ... количество строк
$2 ... количество нуклеотидов в строке

PREPARE dna_length(int, int) AS
SELECT string_agg(CASE ceil(random() * 4)
                   WHEN 1 THEN 'A'
                   WHEN 2 THEN 'C'
                   WHEN 3 THEN 'T'
                   WHEN 4 THEN 'G'
                  END, '') AS dna
FROM   generate_series(1, $1 * $2) g
GROUP  BY g%$1;

Вызов:

EXECUTE dna_length(5,20);

Результат:

| dna                  |
| :------------------- |
| ATCTTCGACACGTCGGTACC |
| GTGGCTGCAGATGAACAGAG |
| ACAGCTTAAAACACTAAGCA |
| TCCGGACCTCTCGACCTTGA |
| CGTGCGGAGTACCCTAATTA |

дБ <> скрипка здесь

Если вам это нужно, рассмотрите функцию вместо этого. См .:

0 голосов
/ 01 мая 2020

PREPARE создает подготовленный оператор, который можно использовать «как есть». Если ваш подготовленный оператор возвращает одну строку, вы можете получить только одну строку. Вы не можете использовать его в других операциях, таких как вставка, например,

. В вашем случае вы можете создать функцию:

create or replace function dna_length(int) returns text as
$$
with t1 as (
    select chr(65) as s
    union
    select chr(67)
    union
    select chr(71)
    union
    select chr(84))
   , t2 as (select s,
                   row_number() over () as rn
            from t1)
   , t3 as (select generate_series(1, $1)    as i,
                   round(random() * 4 + 0.5) as rn)
   , t4 as (select t2.s
            from t2
                     join t3 on (t2.rn = t3.rn))
select array_to_string(array(select s from t4), '') as dna
$$ language sql;

И использовать ее следующим образом:

insert into dna_table(g, dna) select generate_series(1,5), dna_length(20)

Из официального do c:

PREPARE создает подготовленный оператор. Подготовленный оператор - это объект на стороне сервера, который можно использовать для оптимизации производительности. Когда выполняется оператор PREPARE, указанный оператор анализируется, анализируется и переписывается. Когда впоследствии выполняется команда EXECUTE, подготовленный оператор планируется и выполняется. Такое разделение труда позволяет избежать повторяющихся операций анализа анализа, в то же время позволяя плану выполнения зависеть от заданных значений параметров c.

О функциях .

...