这是创建DNA字符串的代码:
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的DNA字符串组成的表,而不只是一行。这是针对PostgreSQL的。
我尝试过:
CREATE TABLE dna_table(g int, dna text);
INSERT INTO dna_table (1, execute dna_length(20));
但是这似乎不起作用。我是绝对的初学者。如何正确执行此操作?
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)
来自官方doc:
PREPARE创建一个准备好的语句。准备好的语句是可用于优化性能的服务器端对象。当执行PREPARE语句时,将分析,分析和重写指定的语句。随后发出EXECUTE命令时,将计划并执行准备好的语句。这种工作分工避免了重复的解析分析工作,同时允许执行计划取决于所提供的特定参数值。
关于functions。
这可以更简单,更快:
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
-%
being the modulo operator进行汇总。
关于%
:
string_agg()
作为准备好的陈述,Concatenate multiple result rows of one column into one, group by another column...行数$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;
结果:
| dna || :------------------- || ATCTTCGACACGTCGGTACC || GTGGCTGCAGATGAACAGAG || ACAGCTTAAAACACTAAGCA || TCCGGACCTCTCGACCTTGA || CGTGCGGAGTACCCTAATTA |
db <>小提琴EXECUTE dna_length(5,20);
如果您非常需要它,请考虑使用一个函数。参见: