在其他功能中执行功能

时间:2019-10-13 22:05:53

标签: postgresql plpgsql

我需要创建一个看起来两个不同的表(通过联接其他表创建)的BRANDS_TYPES和PRODUCTS_LAUNCH的SINGLE函数。它们具有以下结构。

| id | brand_name   | type   |  
| 1  | porsche      | sports |  
| 1  | porsche      | suvs   |  

| id | brand_name  |  prod   | prod_date | sales  | group | prod_remain |  
|  1 | porsche     | carrera |      1991 | 500000 |     1 |           5 |  

我需要返回一个表格,其中包含单个组的选定类型最高销售量中的品牌 。自选定日期以来,品牌必须至少发布1种产品。退货表应汇总按品牌分组并按销售额排序的销售总额,以及剩余产品最少的品牌。 我无法弄清楚如何将这些各种查询合并到一个函数中。

我已经成功地将“过程”分为三个不同的部分,因为对于初学者(我)而言,它们并不过于复杂。第一个功能获取具有特定类型的所有品牌。第二种是查看PRODUCTS_LAUNCH,并返回在特定日期之后至少推出了1种产品并且属于某个组的品牌。第三个函数查看PRODUCTS_LAUNCH,并返回一个表,其中按品牌排序顺序显示剩余产品数量最少,销售额最高。

CREATE OR REPLACE FUNCTION get_type (type_choice VARCHAR)  
    RETURNS TABLE (  
    g_type_name brands_types.type%TYPE,   
    g_brand_id brands_types.brand_id%TYPE,  
    g_brand_name brands_types.brand_name%TYPE)  
AS $$  
BEGIN  
    RETURN QUERY SELECT   
        type_name,  
        brand_id,  
        brand_name  
    FROM brands_types WHERE type ILIKE type_choice;  
END; $$     

CREATE OR REPLACE FUNCTION get_group_date (cutoff_date DATE, group_choice INT)
    RETURNS TABLE ( 
    r_brand_name products_launch.brand_name%TYPE,
    r_date_l products_launch.prod_date%TYPE,
    r_sales products_launch.sales%TYPE,
    r_group products_launch.group%TYPE,
    r_remaining products_launch.prod_remain%TYPE)
AS $$
DECLARE
    i_row record;
BEGIN
    FOR i_row IN 
        (SELECT  
            brand_name,
            prod_date,
            sales,
            group,
            prod_remain
        FROM 
            products_launch
        WHERE prod_date >= cutoff_date AND group = group_choice)
    LOOP
        r_brand_name := upper(i_row.brand_name);
        r_date_l := i_row.prod_date;
        r_sales := i_row.sales;
        r_group := i_row.group;
        r_remaining := i_row.prod_remain;
        RETURN NEXT;
    END LOOP;
END;
$$

CREATE OR REPLACE FUNCTION get_topsales_prodleft (top_t1 INT)
    RETURNS TABLE (
        tp_brand_name products_launch.brand_name%TYPE,
        tp_remaining products_launch.prod_remain%TYPE,  
        tp_sales products_launch.sales%TYPE
        )
AS $$
BEGIN 
    RETURN QUERY        
        SELECT 
            brand_name,
            prod_remain,
            SUM (sales) AS total_sales
        FROM
            products_launch
        GROUP BY
            brand_name,
            prod_remain
        ORDER BY prod_remain DESC, total_sales DESC
        LIMIT top_t1;
END;
$$

每个功能都按预期工作(我认为),但是我需要一个功能。我该如何称呼另一个人并查询退货?

1 个答案:

答案 0 :(得分:1)

首先,我建议简化一下:

CREATE OR REPLACE FUNCTION get_type (type_choice VARCHAR)  
    RETURNS SETOF brands_types
    LANGUAGE SQL
AS $$
    SELECT *
    FROM brands_types
    WHERE type ILIKE type_choice;  
$$     
CREATE OR REPLACE FUNCTION get_group_date (cutoff_date DATE, group_choice INT)
    RETURNS SETOF products_launch
    LANGUAGE SQL
AS $$
    SELECT
        upper(brand_name) AS brand_name,
        prod_date,
        sales,
        group,
        prod_remain
    FROM 
        products_launch
    WHERE prod_date >= cutoff_date AND group = group_choice;
$$
CREATE OR REPLACE FUNCTION get_topsales_prodleft (top_t1 INT)
    RETURNS SETOF products_launch
    LANGUAGE SQL
AS $$
    SELECT 
        brand_name,
        prod_remain,
        SUM (sales) AS total_sales
    FROM
        products_launch
    GROUP BY
        brand_name,
        prod_remain
    ORDER BY prod_remain DESC, total_sales DESC
    LIMIT top_t1;
$$

现在要将它们加入单个查询,您要做的就是将类型与带有品牌名称的launchs一起加入,并通过以下方式过滤求和:

SELECT *
FROM get_topsales_prodleft($1)
WHERE brand_name IN (SELECT brand_name
                     FROM get_type($2)
                     JOIN get_group_date($3, $4) USING (brand_name))

为使此功能按预期工作,我认为您a)需要将LIMIT放到经过过滤的外部查询中,而不是放在get_topsales_prodleft函数的内部,并且您需要删除{{1 }}在upper()中的brand_name上调用,否则联接将无法正常工作。

我还认为,将查询写在单个语句中而不使用任何函数会更简单-或至少省去很多冗长。它会到达

get_group_date