[英]Postgres query to replace CTE query
我有一张如下表
<p> </p>
<table>
<tbody>
<tr>
<th>SELECT * FROM review.tbl_school_review</th>
</tr>
<tr>
<th>review_id</th>
<th>school_id</th>
<th>dept_id</th>
<th>contact_id</th>
<th>rating</th>
<th>comment</th>
<th>review_closed</th>
<th>created_when</th>
<th>modified_when</th>
</tr>
<tr class="odd">
<td>cdaa36be-703c-493a-adbc-093e0b438d64</td>
<td>100</td>
<td>4d811902-acce-448f-9fa8-c48404202f34</td>
<td>776f41c8-727a-4318-a304-815d804dcaa7</td>
<td>1</td>
<td>good</td>
<td>1</td>
<td>2020-01-11 18:58:34</td>
<td>2020-01-11 18:58:34</td>
</tr>
<tr>
<td>2f858144-1598-4179-ab69-96caa67bcc56</td>
<td>100</td>
<td>4d811902-acce-448f-9fa8-c48404202f34</td>
<td>776f41c8-727a-4318-a304-815d804dcaa7</td>
<td>0</td>
<td> </td>
<td>0</td>
<td>2020-01-11 19:00:02</td>
<td>2020-01-11 19:00:02</td>
</tr>
<tr class="odd">
<td>cf7be564-fe3f-4961-8a99-5c14f540693f</td>
<td>100</td>
<td>4d811902-acce-448f-9fa8-c48404202f34</td>
<td>776f41c8-727a-4318-a304-815d804dcaa7</td>
<td>0</td>
<td> </td>
<td>0</td>
<td>2020-01-11 19:00:33</td>
<td>2020-01-11 19:00:33</td>
</tr>
<tr>
<td>a2ba8acc-01cf-45fd-a187-fb7dbbd9abe6</td>
<td>100</td>
<td>5cf9f961-baab-4359-a579-5f4f262c7903</td>
<td>cd7b19a5-5c7b-462b-91d8-6c288ff63968</td>
<td>0</td>
<td> </td>
<td>0</td>
<td>2020-01-11 19:01:52</td>
<td>2020-01-11 19:01:52</td>
</tr>
<tr class="odd">
<td>f7809e23-6fd8-4e3c-9098-38968ec5d194</td>
<td>100</td>
<td>5cf9f961-baab-4359-a579-5f4f262c7903</td>
<td>cd7b19a5-5c7b-462b-91d8-6c288ff63968</td>
<td>0</td>
<td> </td>
<td>0</td>
<td>2020-01-11 19:02:17</td>
<td>2020-01-11 19:02:17</td>
</tr>
</tbody>
</table>
我想在 postgres 中创建一个函数,它将把 school_id 和一个 dept_ids 数组作为参数,它应该返回对 dept 的评级和评论。 如果部门有任何封闭审查,则查询应返回封闭审查的评论和评级。 如果没有关闭的评论,它将返回评分和评论为空
所以查询的结果应该是下面的
<table>
<tbody>
<tr>
<th>SELECT * FROM review.ftm_list_dept_review('{"4d811902-acce-448f-9fa8-c48404202f34","5cf9f961-baab-4359-a579-5f4f262c7903", "0ef7312c-09a4-46af-b694-a14618664a74"}'::uuid[],100)</th>
</tr>
<tr>
<th>school_id</th>
<th>dept_id</th>
<th>rating</th>
<th>review_comment</th>
<th>review_completed</th>
</tr>
<tr class="odd">
<td>100</td>
<td>4d811902-acce-448f-9fa8-c48404202f34</td>
<td>1</td>
<td>good</td>
<td>1</td>
</tr>
<tr>
<td>100</td>
<td>5cf9f961-baab-4359-a579-5f4f262c7903</td>
<td>0</td>
<td> </td>
<td>0</td>
</tr>
</tbody>
</table>
我创建了一个如下所示的函数并且它工作正常,我读到 CTE 对 postgres 的性能不利。 有没有其他方法可以在不使用 cte 的情况下获得结果。
CREATE OR REPLACE FUNCTION review.ftm_list_dept_review(
IN param_dept_id UUID[]
,IN param_school_id INT
)RETURNS TABLE(
school_id INT
,dept_id UUID
,rating INT
,review_comment TEXT
,review_completed INT)
AS $function$
BEGIN
RETURN query
WITH cte_closed_review_details AS(
SELECT COALESCE(ar.rating,0) AS rating
,COALESCE(COMMENT,' ') AS review_comment
,ud.dept_id AS dept_id
,COALESCE(ar.review_closed,0) AS review_completed
FROM (SELECT unnest(param_dept_id ::UUID[] ) AS dept_id) AS ud
LEFT JOIN review.tbl_school_review ar ON ud.dept_id = ar.dept_id AND ar.review_closed = 1 AND ar.school_id = param_school_id
)
SELECT
ar.school_id
,crd.dept_id
,crd.rating
,crd.review_comment
,crd.review_completed :: INT
FROM cte_closed_review_details crd
INNER JOIN review.tbl_school_review ar ON crd.dept_id = ar.dept_id AND ar.school_id = param_school_id
WHERE 1=1
GROUP BY ar.school_id,crd.dept_id,crd.rating,crd.review_comment,crd.review_completed;
END
$function$
LANGUAGE plpgsql
SECURITY DEFINER;
/*
SELECT * FROM review.ftm_list_dept_review('{"4d811902-acce-448f-9fa8-c48404202f34","5cf9f961-baab-4359-a579-5f4f262c7903", "0ef7312c-09a4-46af-b694-a14618664a74"}'::uuid[],100);
*/
CREATE TABLE IF NOT EXISTS review.tbl_school_review
(
review_id UUID NOT NULL
,school_id INT NOT NULL
,dept_id UUID NOT NULL
,contact_id UUID NOT NULL
,rating SMALLINT CONSTRAINT df_review_rating DEFAULT 0 NOT NULL
,comment TEXT CONSTRAINT df_review_comment DEFAULT '' NOT NULL
,review_closed SMALLINT CONSTRAINT df_review_closed DEFAULT 0 NOT NULL
,created_when TIMESTAMP CONSTRAINT df_review_created_datetime DEFAULT (now() at time zone 'utc') NOT NULL
,modified_when TIMESTAMP CONSTRAINT df_review_modified_datetime DEFAULT (now() at time zone 'utc') NOT NULL
,CONSTRAINT pk_school_review_schoolid_deptid_contactid_createdwhen PRIMARY KEY (school_id, dept_id,contact_id,created_when)
,CONSTRAINT un_school_review_review_id UNIQUE (review_id)
);
INSERT INTO review.tbl_school_review (review_id,school_id,dept_id,contact_id,rating,COMMENT,review_closed)
VALUES (
'cdaa36be-703c-493a-adbc-093e0b438d64'::UUID
,100::int
,'4d811902-acce-448f-9fa8-c48404202f34'::UUID
,'776f41c8-727a-4318-a304-815d804dcaa7'::UUID
,1::INT
,'good'::TEXT
,1::integer
);
INSERT INTO review.tbl_school_review (review_id,school_id,dept_id,contact_id)
VALUES (
'2f858144-1598-4179-ab69-96caa67bcc56'::UUID
,100::int
,'4d811902-acce-448f-9fa8-c48404202f34'::UUID
,'776f41c8-727a-4318-a304-815d804dcaa7'::UUID
);
INSERT INTO review.tbl_school_review (review_id,school_id,dept_id,contact_id)
VALUES (
'cf7be564-fe3f-4961-8a99-5c14f540693f'::UUID
,100::int
,'4d811902-acce-448f-9fa8-c48404202f34'::UUID
,'776f41c8-727a-4318-a304-815d804dcaa7'::UUID
);
INSERT INTO review.tbl_school_review (review_id,school_id,dept_id,contact_id)
VALUES (
'a2ba8acc-01cf-45fd-a187-fb7dbbd9abe6'::UUID
,100::int
,'5cf9f961-baab-4359-a579-5f4f262c7903'::UUID
,'cd7b19a5-5c7b-462b-91d8-6c288ff63968'::UUID
);
INSERT INTO review.tbl_school_review (review_id,school_id,dept_id,contact_id)
VALUES (
'f7809e23-6fd8-4e3c-9098-38968ec5d194'::UUID
,100::int
,'5cf9f961-baab-4359-a579-5f4f262c7903'::UUID
,'cd7b19a5-5c7b-462b-91d8-6c288ff63968'::UUID
);
SELECT * FROM review.tbl_school_review ;
您可以将其替换为子查询(将 CTE 定义放在from
before inner join
之后的括号中),但 CTE 不一定具有较差的性能
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.