4

J'ai une requête dans un UDF (ci-dessous) unnest() s un tableau d'entiers et s'y joint, j'ai créé une table temporaire locale dans mon UDF pgplsql puisque je sais que cela fonctionne. Est-il possible d'utiliser unnest directement dans une requête pour effectuer une jointure au lieu de devoir créer une table temporaire?Joindre contre la sortie d'un tableau unnest sans créer une table temporaire

CREATE OR REPLACE FUNCTION search_posts(
    forum_id_ INTEGER, 
    query_ CHARACTER VARYING, 
    offset_ INTEGER DEFAULT NULL, 
    limit_ INTEGER DEFAULT NULL, 
    from_date_ TIMESTAMP WITHOUT TIME ZONE DEFAULT NULL, 
    to_date_ TIMESTAMP WITHOUT TIME ZONE DEFAULT NULL, 
    in_categories_ INTEGER[] DEFAULT '{}' 
    ) 
RETURNS SETOF forum_posts AS $$ 
DECLARE 
    join_string CHARACTER VARYING := ' '; 
    from_where_date CHARACTER VARYING := ' '; 
    to_where_date CHARACTER VARYING := ' '; 
    query_string_ CHARACTER VARYING := ' '; 
    offset_str_ CHARACTER VARYING := ' '; 
    limit_str_ CHARACTER VARYING := ' '; 
BEGIN 
    IF NOT from_date_ IS NULL THEN 
     from_where_date := ' AND fp.posted_at > ''' || from_date_ || ''''; 
    END IF; 

    IF NOT to_date_ IS NULL THEN 
     to_where_date := ' AND fp.posted_at < ''' || to_date_ || ''''; 
    END IF; 

    IF NOT offset_ IS NULL THEN 
     offset_str_ := ' OFFSET ' || offset_; 
    END IF; 

    IF NOT limit_ IS NULL THEN 
     limit_str_ := ' LIMIT ' || limit_; 
    END IF; 

    IF NOT limit_ IS NULL THEN 
    END IF; 

    CREATE LOCAL TEMP TABLE un_cat(id) ON COMMIT DROP AS (select * from unnest(in_categories_)) ; 

    if in_categories_ != '{}' THEN 
     join_string := ' INNER JOIN un_cat uc ON uc.id = fp.category_id ' ; 
    END IF; 
s 
    query_string_ := ' 
    SELECT fp.* 
    FROM forum_posts fp' || 
     join_string 
    || 
    'WHERE fp.forum_id = ' || forum_id_ || ' AND 
    to_tsvector(''english'',fp.post_text) @@ to_tsquery(''english'','''|| query_||''')' || 
     from_where_date || 
     to_where_date || 
     offset_str_ || 
     limit_str_ 
    || ';'; 

    RAISE NOTICE '%', query_string_; 

    RETURN QUERY 
    EXECUTE query_string_; 
END; 
$$ LANGUAGE plpgsql; 

select * from search_posts(forum_id_:=1, query_:='scout & rampage', in_categories_ := '{71}'); 

La raison pour laquelle je veux faire est que I want to be able to to have a look at the query plan without having to resort to look at the auto explain output in the server log. Une table temporaire locale empêche cela. Par exemple, je ne peux pas copier coller la requête résultante et l'exécuter textuellement.

+0

[Donc, avez-vous votre réponse ?] (http://meta.stackexchange.com/a/5235/169168) –

Répondre

4

Est-il possible d'utiliser directement unnest() dans une requête pour effectuer une jointure au lieu d'avoir à créer une table temporaire?

Oui, et c'est beaucoup plus efficace.
(Sauf si vous avez besoin des données non imbriquées dans plusieurs requêtes qui ne peuvent être enchaînées dans un (données-modification) CTE.)

Considérons cet exemple:

SELECT * 
FROM tbl t 
JOIN unnest('{10,11,12}'::int[]) AS x(tbl_id) USING (tbl_id); 
Questions connexes