我有以下sql,我想从gene_info
返回sample_info
,从id_card_no
返回person_info
,从race
返回person_info
,然后gene_info
中的sample_dna_gene
。
外键:person_info.id
= sample_info.self_object_id
和sample_info.id
= sample_dng_gene.sample_id
我要从id
中提取sample_info
的第一个,并从gene_info
中提取sample_dna_gene
的第一个,所以我可能需要使用group by,但看不到其他方式可以做到这一点。我还需要为其他列添加max()。这看起来效率低下,我想看看是否还有其他方法可以做到这一点。该数据库具有多达十亿条记录,因此速度很重要。
select to_char(sdg.gene_info), max(aa.pid), max(aa.idn), max(aa.r)
from (select max(pi.person_name),
max(pi.id) pid,
si.id sid,
max(pi.id_card_no) idn,
max(pi.race) r
from person_info pi
join sample_info si
on pi.id = si.self_object_id
group by si.id) aa
join sample_dna_gene sdg
on sdg.sample_id = aa.sid
where aa.pid in ('...')
group by to_char(sdg.gene_info)
答案 0 :(得分:0)
因此,第一件事是您需要限制检索到的人员的集合。这意味着where aa.pid in (...)
实际上应该是where pi.id in ('...')
。
第二,应该有一种更有效的方法来限制sample_info
记录的集合。最好应该有一些业务逻辑(采样日期?状态?)。但是您可以使用解析函数来获取最早的数据。
真的不确定为什么在外部查询中有GROUP BY。所有这些MAX()
调用都不会更改结果集。只是不必要的循环浪费。
with aa as (
select pi.person_name
, pi.id as pid
, pi.id_card_no
, pi.race
, si.id as sid
, row_number() over (partition by pi.id order by si.self_object_id ) as rn
from person_info pi
join sample_info si
on pi.id = si.self_object_id
where pi.id in ('...')
)
select aa.pid
, aa.person_name
, aa.race
, aa.id_card_no
, sdg.gene_info
from aa
join sample_dna_gene sdg
on sdg.sample_id = aa.sid
where aa.rn = 1 -- just get the first matched `sample_info.id` for each `person_info`.
一个缺点是,在编写SQL时,将值列表pi.id in ('...')
注入子查询很容易,但是在通过诸如Spring之类的框架调用该SQL时,难度更大。但是,您应该首先专注于正确设置SQL,然后再担心如何运行它。