我试图在postgres中将三个表链接在一起。
所有三个表都是从子查询生成的。第一个表通过变量call_sign链接到第二个表作为FULL JOIN(因为我想要来自两个表的条目的超集)。第三个表有一个INNER JOIN,第二个表也在call_sign上(但理论上可以链接到第一个表)
查询运行但很慢,我觉得随着我添加更多数据会变得更慢。我意识到我可以采取一些措施来加快速度 - 比如不在子查询中提取不必要的数据,也不会动态地将文本转换为数字。但有没有更好的方法来构建这三个表之间的JOIN?
任何建议都会受到赞赏,因为我是postgres的新手。
这是代码:
select
(CASE
WHEN tmp1.frequency_assigned is NULL
THEN tmp2.lower_frequency
ELSE tmp1.frequency_assigned END) as master_frequency,
(CASE
WHEN tmp1.call_sign is NULL
THEN tmp2.call_sign
ELSE tmp1.call_sign END) as master_call_sign,
(CASE
WHEN tmp1.entity_type is NULL
THEN tmp2.entity_type
ELSE tmp1.entity_type END) as master_entity_type,
(CASE
WHEN tmp1.licensee_id is NULL
THEN tmp2.licensee_id
ELSE tmp1.licensee_id END) as master_licensee_id,
(CASE
WHEN tmp1.entity_name is NULL
THEN tmp2.entity_name
ELSE tmp1.entity_name END) as master_entity_name,
tmp3.market_name
FROM
(select cast(replace(frequency_assigned, ',','.') as decimal) AS frequency_assigned,
frequency_upper_band,
f.uls_file_number,
f.call_sign,
entity_type,
licensee_id,
entity_name
from combo_fr f INNER JOIN combo_en e
ON f.call_sign=e.call_sign
ORDER BY frequency_assigned DESC) tmp1
FULL JOIN
(select cast(replace(lower_frequency, ',','.') as decimal) AS lower_frequency,
upper_frequency,
e.uls_file_number,
mf.call_sign,
entity_type,
licensee_id,
entity_name
FROM market_mf mf INNER JOIN combo_en e
ON mf.call_sign=e.call_sign
ORDER BY lower_frequency DESC) tmp2
ON tmp1.call_sign=tmp2.call_sign
INNER JOIN
(select en.call_sign,
mk.market_name
FROM combo_mk mk
INNER JOIN combo_en en
ON mk.call_sign=en.call_sign) tmp3
ON tmp2.call_sign=tmp3.call_sign
ORDER BY master_frequency DESC;
答案 0 :(得分:0)
如果可以的话,你会想要解除这些查询并在一个联接中完成所有操作。像这样的东西:
select <whatever you need>
from combo_fr f
JOIN combo_en e ON f.call_sign=e.call_sign
JOIN market_mf mf mf ON mf.call_sign=e.call_sign
JOIN combo_mk mk ON mk.call_sign=en.call_sign
我不能完全理解你正在做的事情,但是为了处理呼号不会出现或不出现的地方,一些连接条款可能必须成为LEFT JOIN。
答案 1 :(得分:0)
在所有四个相关表格的call_sign
上创建索引后,试试这个:
WITH nodup AS (
SELECT call_sign FROM market_mf
EXCEPT SELECT call_sign FROM combo_fr
) SELECT
CAST(REPLACE(u.master_frequency_string, ',','.') AS DECIMAL)
AS master_frequency,
u.call_sign AS master_call_sign,
u.entity_type AS master_entity_type,
u.licensee_id AS master_licensee_id,
u.entity_name AS master_entity_name,
combo_mk.market_name
FROM (SELECT frequency_assigned AS master_frequency_string, call_sign,
entity_type, licensee_id, entity_name
FROM combo_fr
UNION ALL SELECT lower_frequency, call_sign,
entity_type, licensee_id, entity_name
FROM market_mf INNER JOIN nodup USING (call_sign)
) AS u
INNER JOIN combo_en USING (call_sign)
INNER JOIN combo_mk USING (call_sign)
ORDER BY 1 DESC;
我发布这个是因为这是理解你需要的最简单方法。
call_sign
和market_mf
中都没有显示combo_fr
个值
WITH nodup ...
,INNER JOIN nodup ...
和call_sign
可以省略。combo_fr
在market_mf
和i++
中都是唯一的(=每个表中没有两条记录具有相同的值),即使可以存在可以出现在两个表中的值。