首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >避免多次连接同一个表

避免多次连接同一个表
EN

Database Administration用户
提问于 2015-07-17 09:31:35
回答 1查看 15.4K关注 0票数 3

我有两张桌子:

代码语言:javascript
复制
CREATE TABLE one (
  id int4 primary key,
  p_id int4,
  k_id int4,
  c_id int4
);

CREATE TABLE two(
 id int4 primary key,
 p_id int4,
 k_id int4,
 t_id int4,
 pos int4
);

one:是一个联接表,我在本报告中使用它只是因为c_id和限制行数。

two:包含我的数据,一个p_idk_idt_id可以有很多pos,所以我对它们进行分组并使用min()来获得最小pos。我尝试了一些方法来获取k_idp_id 这里有个方法的所有数据(使用这个解决方案,我无法通过pos订购),所以我最终完成了这个(见小提琴)

代码语言:javascript
复制
SELECT
  o.p_id,
  o.k_id,
  min(t.pos) as t_pos,
  min(t1.pos) as t1_pos
FROM one o
  LEFT JOIN two t ON t.p_id = o.p_id 
    AND t.k_id = o.k_id
    AND t.t_id = 1
  LEFT JOIN two t1 ON t1.p_id = o.p_id 
    AND t1.k_id = o.k_id
    AND t1.t_id = 2
WHERE o.p_id = 1 AND o.c_id = 1
GROUP BY 1, 2
LIMIT 1

这个解决方案比@Erwin Brandstetter的解决方案来自另一个帖子慢2-3倍,但是排序t_post1_pos是可能的,并且还可以获取type_id = 1pos = 1等所有数据。

是否有更好的方法来实现相同的输出,提高速度并能够对我的数据进行排序(t_post1_pos列)?

EN

回答 1

Database Administration用户

回答已采纳

发布于 2015-07-17 10:17:59

试试这个对你有多好

对于两个t_id的表2,将左联接转换为一个内连接。在计算min时,使用case语句根据值t_id拆分成两列。我们在这里保存的是两次扫描表和一个内部连接,而不是左连接。

代码语言:javascript
复制
SELECT
    o.p_id,
    o.k_id,
    MIN(case when t.t_id = 1 then t.pos else null end) AS t_pos,
    MIN(case when t.t_id = 2 then t.pos else null end) AS t1_pos
FROM
    one o
INNER JOIN two T ON t.p_id = o.p_id
AND t.k_id = o.k_id
AND t.t_id =any ( 1,2)
WHERE
    o.p_id = 1
AND o.c_id = 1
GROUP BY
    1,
    2
LIMIT 1
票数 2
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/107316

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档