在POSTGRES 9.1中运行sql-query。该查询使用24个LEFT JOIN。 每个连接的表都可以有1到10-15个与上一个表相关的数据行。作为sql-query的结果,我有很多数据行,彼此相差1个值
SQL查询示例:
SELECT
asw.surname,
asw.firstname,
asw.fathername,
asw.birthday,
asbe.institue_title,
asht.honour_type
/* Other fields are hidden to simplify example */
FROM
/* Table of staff */
agency_socworker AS asw
LEFT JOIN
/* Table contains staff honours */
agency_socworkerhonours AS ash
ON asw.id = ash.socworker_id
LEFT JOIN
/* Table contains name of the certain honour_id */
agency_socworker_honourtype AS asht
ON ash.honour_name_id = asht.id
LEFT JOIN
/* Table contains education data */
agency_socworker_base_edu AS asbe
ON asbe.socworker_id = asw.id
/* Other part of query is hidden to simplify example */
ORDER BY
asw.surname ASC
结果示例:
surname---firstname---fathername---birthday-----honour_type----institue_title1
Surname---firstname---fathername---1965-01-01---TYPE1----------institue_title1
Surname---firstname---fathername---1965-01-01---TYPE2----------institue_title1
Surname---firstname---fathername---1965-01-01---TYPE3----------institue_title1
Surname---firstname---fathername---1965-01-01---TYPE4----------institue_title1
Surname---firstname---fathername---1965-01-01---TYPE5----------institue_title1
Surname---firstname---fathername---1965-01-01---TYPE1----------institue_title2
Surname---firstname---fathername---1965-01-01---TYPE2----------institue_title2
Surname---firstname---fathername---1965-01-01---TYPE3----------institue_title2
Surname---firstname---fathername---1965-01-01---TYPE4----------institue_title2
Surname---firstname---fathername---1965-01-01---TYPE5----------institue_title2
我想得到以下内容:
surname---firstname---fathername---birthday--------honour_type----------------------institue_title
Surname---firstname---fathername---1965-01-01---TYPE1, TYPE2, TYPE3, TYPE4, TYPE5---institue_title1, institue_title2
我使用array_agg函数来实现这个目标:
SELECT
asw.surname,
asw.firstname,
asw.fathername,
asw.birthday,
array_agg( asbe.institue_title ) AS honour_type
array_agg( asht.honour_type ) AS honour_type
/* Other fields are hidden to simplify example */
FROM
/* Table of staff */
agency_socworker AS asw
LEFT JOIN
/* Table contains staff honours */ agency_socworkerhonours AS ash
ON asw.id = ash.socworker_id
LEFT JOIN
/* Table contains name of the certain honour_id */
agency_socworker_honourtype AS asht
ON ash.honour_name_id = asht.id
LEFT JOIN
/* Table contains education data */
agency_socworker_base_edu AS asbe
ON asbe.socworker_id = asw.id
GROUP BY
asw.surname,
asw.firstname,
asw.fathername,
asw.birthday
ORDER BY
asw.surname ASC
但这需要" GROUP BY"声明不在" array_agg"功能。由于完整的SQL查询包含24个连接表,我必须使用
GROUP BY
asw.surname,
asw.firstname,
asw.fathername,
asw.birthday,
ag.shortname,
agr.shortname,
agr.fullname,
agdis.shortname,
agdis.fullname,
aorg.name,
agc.name,
agc.atype,
asnji.id,
asnji.new_job_contract_date,
assp.struct_name,
agdep.number,
agdep_type.name,
agdep_type.dtype,
aswl.work_length_checkdate,
aswl.work_length_protection_length_years,
aswl.work_length_protection_length_days,
aswl.work_length_protection_length_months
这会减慢查询速度。使用" group by"获取前100个数据行需要2秒钟。没有" array_agg" " group by"声明需要250毫秒,但我必须有分页。我不能分页,因为我不知道有多少数据行可以获得100个独特的行。
答案 0 :(得分:0)
您可以做的最好的事情是预先聚合并重新加入。我不确定性能影响,但是表达式更少。对其他表使用相同的技术
with asw_agg as (
select
asw.id,
array_agg(asbe.institue_title) as institute_title,
array_agg(asht.honour_type) as honour_type
from
agency_socworker asw
left join
agency_socworkerhonours ash on asw.id = ash.socworker_id
left join
agency_socworker_honourtype asht on ash.honour_name_id = asht.id
left join
agency_socworker_base_edu asbe on asbe.socworker_id = asw.id
group by asw.id
)
select
asw.surname,
asw.firstname,
asw.fathername,
asw.birthday,
asw_agg.honour_type,
asw_agg.institute_title
from
asw
inner join
asw_agg using (id)
order by asw.surname asc