繁体   English   中英

Postgres 查询替换 CTE 查询

[英]Postgres query to replace CTE query

我有一张如下表

<p>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM