PostgreSQL选择联接表和一个函数

PostgreSQL选择联接表和一个函数,postgresql,Postgresql,我的数据库中有一个函数,它返回一个表。我要做的是选择加入一个表和那个函数。 我看到它不能在FROM位置完成,但是如果我将函数放在select中,它需要花费太长的时间来执行。 我的SQL是: select "Grades"."id", SUPRIMENTO_LOJA("Grades"."id", 30, 1, 1) from "Grades" 这需要500多秒才能执行 我也试过了,但它返回了一个错误 select * from "Grades",

我的数据库中有一个函数,它返回一个表。我要做的是选择加入一个表和那个函数。 我看到它不能在FROM位置完成,但是如果我将函数放在select中,它需要花费太长的时间来执行。 我的SQL是:

select
    "Grades"."id",
    SUPRIMENTO_LOJA("Grades"."id", 30, 1, 1)
from
    "Grades"
这需要500多秒才能执行

我也试过了,但它返回了一个错误

select
    *
from
    "Grades",
    SUPRIMENTO_LOJA("Grades"."id", 30, 1, 1)
让这一选择发挥作用的最佳方式是什么

编辑: 其功能是:

CREATE OR REPLACE FUNCTION suprimento_loja(grade_id integer, vendas_dias integer, lojaId integer, embalagem numeric(15, 4)) 
RETURNS TABLE(qtd integer, maximo integer, ultFornecedor character varying(50), 
ultCompra character varying(10), ultVenda character varying(10), classeLoja character varying(1), 
vendas integer, sugestao integer, giroLoja numeric(15, 4))
AS $$
DECLARE     
    qtde1 integer;
    vendasdiae1 integer;
    maximoe1 integer;
    ultvendae1 timestamp;
    ultcomprae1 timestamp;
    ultforne1 varchar(50);
    classee1 varchar(1);
    vendase1 integer;
    qtde2 integer;
    vendasdiae2 integer;
    maximoe2 integer;
    ultvendae2 timestamp;
    ultcomprae2 timestamp;
    ultforne2 varchar(50);
    vendase2 integer;
    qtde3 integer;
    vendasdiae3 integer;
    maximoe3 integer;
    ultvendae3 timestamp;
    ultcomprae3 timestamp;
    ultforne3 varchar(50);
    vendase3 integer;
    giroe1 numeric(15, 4);
    giroe2 numeric(15, 4);
    giroe3 numeric(15, 4);
BEGIN
    with vendas as (
    select
        sum(coalesce("quantidade", 0)) as vendas_periodo,
        "inventario_id"
    from
        "WVItens"
    where
        "WVItens"."ultimoDownload" between current_timestamp - (select to_interval(vendas_dias))
        and current_timestamp and coalesce("status", '') = ''
    group by
        "inventario_id")
    select into qtde1, vendasdiae1, maximoe1, ultvendae1, ultcomprae1, ultforne1, classee1, vendase1, giroe1
        cast("quantidadeAtual" as integer), 
        cast("vendasPorDia" as integer), 
        cast("maximoEmDias" as integer), 
            "dataUltimaVenda", 
        "dataUltimaCompra", 
        "ultimoFornecedor", 
        "classe", 
        cast(vendas_periodo as integer),
        coalesce("giro", 0)
    from 
        "Inventarios", 
        "Lojas",
        vendas
    where 
                "Inventarios"."estoque_id" = "Lojas"."estoque1_id" and 
        coalesce("Inventarios"."status", '') = '' and
        "Inventarios"."id" = vendas."inventario_id" and
        "Lojas"."id" = lojaId and 
        "grade_id" = gradeId;

    with vendas as (
    select
        sum(coalesce("quantidade", 0)) as vendas_periodo,
        "inventario_id"
    from
        "WVItens"
    where
        "WVItens"."ultimoDownload" between current_timestamp - (select to_interval(vendas_dias))
        and current_timestamp and coalesce("status", '') = ''
    group by
        "inventario_id")        
    select into qtde2, vendasdiae2, maximoe2, ultvendae2, ultcomprae2, ultforne2, vendase2, giroe2
        cast("quantidadeAtual" as integer), 
        cast("vendasPorDia" as integer), 
        cast("maximoEmDias" as integer), 
        "dataUltimaVenda", 
        "dataUltimaCompra", 
        "ultimoFornecedor", 
        cast(vendas_periodo as integer),
        coalesce("giro", 0)
    from 
        "Inventarios", 
                "Lojas",
            vendas
    where 
        "Inventarios"."estoque_id" = "Lojas"."estoque2_id" and 
        coalesce("Inventarios"."status", '') = '' and
        "Inventarios"."id" = vendas."inventario_id" and
        "Lojas"."id" = lojaId and 
        "grade_id" = gradeId;   

    with vendas as (
    select
        sum(coalesce("quantidade", 0)) as vendas_periodo,
        "inventario_id"
    from
        "WVItens"
    where
        "WVItens"."ultimoDownload" between current_timestamp - (select to_interval(vendas_dias))
        and current_timestamp and coalesce("status", '') = ''
    group by
        "inventario_id")            
    select into qtde3, vendasdiae3, maximoe3, ultvendae3, ultcomprae3, ultforne3, vendase3, giroe3
        cast("quantidadeAtual" as integer), 
        cast("vendasPorDia" as integer), 
        cast("maximoEmDias" as integer), 
        "dataUltimaVenda", 
        "dataUltimaCompra", 
        "ultimoFornecedor", 
        cast(vendas_periodo as integer),
        coalesce("giro", 0)
    from 
        "Inventarios", 
        "Lojas",
        vendas
    where 
        "Inventarios"."estoque_id" = "Lojas"."estoque2_id" and 
        coalesce("Inventarios"."status", '') = '' and
        "Inventarios"."id" = vendas."inventario_id" and
        "Lojas"."id" = lojaId and 
        "grade_id" = gradeId;   

    qtd := 0;
    IF (qtde1 is not null) THEN
        qtd := qtd + qtde1;
    END IF; 
    IF (qtde2 is not null) THEN
        qtd := qtd + qtde2;
    END IF; 
    IF (qtde3 is not null) THEN
        qtd := qtd + qtde3;
    END IF;         

    giroLoja = (giroe1 + giroe2 + giroe3) / 3;

    maximo := 0;
    IF ((maximoe1 is not null) and (vendasdiae1 is not null)) THEN
        maximo := maximo + (maximoe1 * vendasdiae1);
    END IF;
    IF ((maximoe2 is not null) and (vendasdiae2 is not null)) THEN
        maximo := maximo + (maximoe2 * vendasdiae2);
    END IF;
    IF ((maximoe3 is not null) and (vendasdiae3 is not null)) THEN
        maximo := maximo + (maximoe3 * vendasdiae3);
    END IF;

    IF (qtde1 is null) THEN
        qtde1 := 0;
    END IF; 
    IF (qtde2 is null) THEN
        qtde2 := 0;        
    END IF; 
    IF (qtde3 is null) THEN
        qtde3 := 0;        
    END IF; 
    IF (maximoe1 is null) THEN
        maximoe1 := 0;        
    END IF; 
    IF (maximoe2 is null) THEN
        maximoe2 := 0;
    END IF; 
    IF (maximoe3 is null) THEN
        maximoe3 := 0;                        
    END IF; 
    IF (vendasdiae1 is null) THEN
        vendasdiae1 := 0;                
    END IF; 
    IF (vendasdiae2 is null) THEN
        vendasdiae2 := 0;
    END IF; 
    IF (vendasdiae3 is null) THEN
        vendasdiae3 := 0;                                
    END IF; 
    IF (vendase1 is null) THEN
        vendase1 := 0;                        
    END IF; 
    IF (vendase2 is null) THEN
        vendase2 := 0;
    END IF; 
    IF (vendase3 is null) THEN
        vendase3 := 0;  
    END IF; 

    ultCompra := '';
    ultVenda := '';
    ultFornecedor := '';


    IF (ultcomprae1 is null) THEN
        IF (ultcomprae2 is null) THEN
            IF (ultcomprae3 is not null) THEN
                ultCompra := cast(extract(day from ultcomprae3) || '/' || extract(month from ultcomprae3) || '/' || extract(year from ultcomprae3) as varchar(10));
                ultFornecedor := ultforne3;
            END IF;
        ELSE
            IF ((ultcomprae3 is null) or (ultcomprae2 > ultcomprae3)) THEN
                ultCompra := cast(extract(day from ultcomprae2) || '/' || extract(month from ultcomprae2) || '/' || extract(year from ultcomprae2) as varchar(10));
                ultFornecedor := ultforne2;
            ELSE
                ultCompra := cast(extract(day from ultcomprae3) || '/' || extract(month from ultcomprae3) || '/' || extract(year from ultcomprae3) as varchar(10));
                ultFornecedor := ultforne3;
            END IF;
        END IF;
    ELSE
        IF ((ultcomprae2 is null) or (ultcomprae1 > ultcomprae2)) THEN
            IF ((ultcomprae3 is null) or (ultcomprae1 > ultcomprae3)) THEN
                ultCompra := cast(extract(day from ultcomprae1) || '/' || extract(month from ultcomprae1) || '/' || extract(year from ultcomprae1) as varchar(10));
                ultFornecedor := ultforne1;
            ELSE
                IF (ultcomprae3 is not null) THEN
                    ultCompra := cast(extract(day from ultcomprae3) || '/' || extract(month from ultcomprae3) || '/' || extract(year from ultcomprae3) as varchar(10));
                    ultFornecedor := ultforne3;             
                END IF;
            END IF;
        ELSE
            IF ((ultcomprae3 is null) or (ultcomprae2 > ultcomprae3)) THEN
                ultCompra := cast(extract(day from ultcomprae2) || '/' || extract(month from ultcomprae2) || '/' || extract(year from ultcomprae2) as varchar(10));
                ultFornecedor := ultforne2;
            ELSE
                ultCompra := cast(extract(day from ultcomprae3) || '/' || extract(month from ultcomprae3) || '/' || extract(year from ultcomprae3) as varchar(10));
                ultFornecedor := ultforne3;
            END IF;     
        END IF;
    END IF; 

    IF (ultvendae1 is null) THEN
        IF (ultvendae2 is null) THEN
            IF (ultvendae3 is not null) THEN
                ultVenda := cast(extract(day from ultvendae3) || '/' || extract(month from ultvendae3) || '/' || extract(year from ultvendae3) as varchar(10));
            END IF;
        ELSE
            IF ((ultvendae3 is null) or (ultvendae2 > ultvendae3)) THEN
                ultVenda := cast(extract(day from ultvendae2) || '/' || extract(month from ultvendae2) || '/' || extract(year from ultvendae2) as varchar(10));
            ELSE
                ultVenda := cast(extract(day from ultvendae3) || '/' || extract(month from ultvendae3) || '/' || extract(year from ultvendae3) as varchar(10));
            END IF;
        END IF;
    ELSE
        IF ((ultvendae2 is null) or (ultvendae1 > ultvendae2)) THEN
            IF ((ultvendae3 is null) or (ultvendae1 > ultvendae3)) THEN
                ultVenda := cast(extract(day from ultvendae1) || '/' || extract(month from ultvendae1) || '/' || extract(year from ultvendae1) as varchar(10));
            ELSE
                IF (ultvendae3 is not null) THEN
                    ultVenda := cast(extract(day from ultvendae3) || '/' || extract(month from ultvendae3) || '/' || extract(year from ultvendae3) as varchar(10));
                END IF;
            END IF;
        ELSE
            IF ((ultvendae3 is null) or (ultvendae2 > ultvendae3)) THEN
                ultVenda := cast(extract(day from ultvendae2) || '/' || extract(month from ultvendae2) || '/' || extract(year from ultvendae2) as varchar(10));
            ELSE
                ultVenda := cast(extract(day from ultvendae3) || '/' || extract(month from ultvendae3) || '/' || extract(year from ultvendae3) as varchar(10));
            END IF;     
        END IF;
    END IF;     


    vendas = vendase1 + vendase2 + vendase3;
    classeLoja := classee1;

    IF ((qtde1 + qtde2 + qtde3) > ((maximoe1 * vendasdiae1) + (maximoe2 * vendasdiae2) + (maximoe3 * vendasdiae3))) THEN
        sugestao := 0;
    ELSE
        sugestao := cast(((((maximoe1 * vendasdiae1) + (maximoe2 * vendasdiae2) + (maximoe3 * vendasdiae3)) - (qtde1 + qtde2 + qtde3)) + 0.4) as integer);
    END IF;


    RETURN NEXT;
END
$$ LANGUAGE plpgsql;
我尝试了一些查询,但它太长了,甚至不是我需要的最终查询

    with suprimento as (
        with vendas as (
            select
                sum(coalesce("quantidade", 0)) as vendas_periodo,
                "inventario_id"
            from
                "WVItens"
            where
                "WVItens"."ultimoDownload" between current_timestamp - (select to_interval(30))
                and current_timestamp and coalesce("status", '') = ''
            group by
                "inventario_id")
        select
            "grade_id",
            "estoque_id",
            sum(cast("quantidadeAtual" as integer)) as "quantidade", 
            sum(cast("vendasPorDia" as integer)) as "vendasPorDia", 
            sum(cast("maximoEmDias" as integer)) as "maximoEmDias", 
            max("dataUltimaVenda") as "ultVenda", 
            max("dataUltimaCompra") as "ultCompra", 
            max("ultimoFornecedor") as "ultFornecedor", 
            sum(cast(vendas_periodo as integer)) as "vendasPeriodo",
            max(coalesce("giro", 0)) as "giro"
        from 
            "Inventarios" 
            left outer join vendas on ("Inventarios"."id" = vendas."inventario_id")
        where 
            coalesce("Inventarios"."status", '') = ''           
        group by
            "grade_id", "estoque_id")    
新编辑

我尝试只进行一次查询,但它一直在运行(超过800秒),查询是:

WITH suprimento_loja as (
WITH suprimento as (
    WITH vendas as (
      SELECT "inventario_id"
        , SUM(coalesce("quantidade", 0)) as vendas_periodo
      FROM "WVItens" vwi
      WHERE vwi."ultimoDownload" between current_timestamp - (SELECT to_interval(30))
        AND current_timestamp
        AND coalesce("status", '') = ''
      GROUP BY "inventario_id"
    )
    SELECT
        "estoque_id",
        "grade_id",
        "classe" as classe
        , cast("quantidadeAtual" as integer) as qtd
        , cast("vendasPorDia" as integer) as vendasDia
        , cast("maximoEmDias" as integer) as maximo
        , coalesce("dataUltimaVenda", timestamp'01.01.1980') as ultVenda
        , "dataUltimaCompra" as ultCompra
        , "ultimoFornecedor" as ultForn
        , cast(vendas_periodo as integer) as vendas_periodo
        , coalesce("giro", 0) as giro
    FROM "Inventarios"  inv
    LEFT OUTER JOIN vendas ve ON inv."id" = ve."inventario_id"
    )
select
    lo."id" as id,
    e1."grade_id" as grade_id,
    e1.ultVenda,
    case
    when e1.ultVenda > coalesce(e2.ultVenda, timestamp'01.01.1980') and e1.ultVenda > coalesce(e3.ultVenda, timestamp'01.01.1980')
    then e1.ultVenda
    else
        case 
        when coalesce(e2.ultVenda, timestamp'01.01.1980') > coalesce(e3.ultVenda, timestamp'01.01.1980')
        then e2.ultVenda
        else e3.ultVenda
        end
    end as ultVenda,
    case
    when e1.ultCompra > coalesce(e2.ultCompra, timestamp'01.01.1980') and e1.ultCompra > coalesce(e3.ultCompra, timestamp'01.01.1980')
    then e1.ultCompra
    else
        case 
        when coalesce(e2.ultCompra, timestamp'01.01.1980') > coalesce(e3.ultCompra, timestamp'01.01.1980')
        then e2.ultCompra
        else e3.ultCompra
        end
    end as ultCompra,
    case
    when e1.ultCompra > coalesce(e2.ultCompra, timestamp'01.01.1980') and e1.ultCompra > coalesce(e3.ultCompra, timestamp'01.01.1980')
    then e1.ultForn
    else
        case 
        when coalesce(e2.ultCompra, timestamp'01.01.1980') > coalesce(e3.ultCompra, timestamp'01.01.1980')
        then e2.ultForn
        else e3.ultForn
        end
    end as ultForn,
    coalesce(e1.vendas_periodo, 0) + coalesce(e2.vendas_periodo, 0) + coalesce(e3.vendas_periodo, 0) as vendas_periodo,
    e1.classe,
    (coalesce(e1.maximo, 0) * coalesce(e1.vendasDia, 0)) + (coalesce(e2.maximo, 0) * coalesce(e2.vendasDia, 0)) + (coalesce(e3.maximo, 0) * coalesce(e3.vendasDia, 0)) as maximo,
    coalesce(e1.giro, 0) as giro,
    coalesce(e1.qtd, 0) + coalesce(e2.qtd, 0) + coalesce(e3.qtd, 0) as qtde,
    case
        when coalesce(e1.giro, 0) = 0
        then 0
        else
        case 
            when ((coalesce(e1.qtd, 0) + coalesce(e2.qtd, 0) + coalesce(e3.qtd, 0)) > ((coalesce(e1.maximo, 0) * coalesce(e1.vendasDia, 0)) + (coalesce(e2.maximo, 0) * coalesce(e2.vendasDia, 0)) + (coalesce(e3.maximo, 0) * coalesce(e3.vendasDia, 0))))
            then 0
            else cast(((((coalesce(e1.maximo, 0) * coalesce(e1.vendasDia, 0)) + (coalesce(e2.maximo, 0) * coalesce(e2.vendasDia, 0)) + (coalesce(e3.maximo, 0) * coalesce(e3.vendasDia, 0))) 
              - (coalesce(e1.qtd, 0) + coalesce(e2.qtd, 0) + coalesce(e3.qtd, 0))) + 0.4) as integer)
        end 
    end as sugestao
from
    "Lojas" lo
    LEFT OUTER JOIN suprimento e2 ON e2."estoque_id" = lo."estoque2_id"
    LEFT OUTER JOIN suprimento e3 ON e3."estoque_id" = lo."estoque3_id"
    JOIN suprimento e1 ON e1."estoque_id" = lo."estoque1_id")

SELECT
    gr."id",
    sl1.*,
    sl2.*,
    sl3.*,
    sl4.*,
    sl5.*,
    sl6.*
FROM
    "Grades" gr
    JOIN suprimento_loja sl1 ON sl1."grade_id" = gr."id"
    JOIN suprimento_loja sl2 ON sl2."grade_id" = gr."id"
    JOIN suprimento_loja sl3 ON sl3."grade_id" = gr."id"
    JOIN suprimento_loja sl4 ON sl4."grade_id" = gr."id"
    JOIN suprimento_loja sl5 ON sl5."grade_id" = gr."id"
    JOIN suprimento_loja sl6 ON sl6."grade_id" = gr."id"
WHERE
    sl1."id" = 1 AND
    sl2."id" = 2 AND
    sl3."id" = 3 AND
    sl4."id" = 4 AND
    sl5."id" = 5 AND
    sl6."id" = 6 

我使用了别名和join,因此您可以轻松阅读

现在您可以做的唯一一件事是加快查询速度—重新生成函数以节省时间


在PostgreSQL 9.3中,您可以将第二个查询变量与
横向
一起使用,但速度不会明显加快。

这只是经过编辑的正文(未经测试,希望我没有输入任何错误;-):


乍一看,似乎您正在使用不同的常量执行三次完全相同的查询,在我看来,这些常量是次字节。

我用另一种方式实现了它。 如果有人遇到类似问题,我得到的解决方案是:

SELECT 
    gr.id,
    max(CASE sl.id WHEN 1 THEN sl.ultVenda ELSE timestamp'01.01.1980' END) AS ultVenda_l1,
    max(CASE sl.id WHEN 2 THEN sl.ultVenda ELSE timestamp'01.01.1980' END) AS ultVenda_l2,
    max(CASE sl.id WHEN 3 THEN sl.ultVenda ELSE timestamp'01.01.1980' END) AS ultVenda_l3,
    max(CASE sl.id WHEN 4 THEN sl.ultVenda ELSE timestamp'01.01.1980' END) AS ultVenda_l4,
    max(CASE sl.id WHEN 5 THEN sl.ultVenda ELSE timestamp'01.01.1980' END) AS ultVenda_l5,
    max(CASE sl.id WHEN 6 THEN sl.ultVenda ELSE timestamp'01.01.1980' END) AS ultVenda_l6,
    max(CASE sl.id WHEN 1 THEN sl.ultCompra ELSE timestamp'01.01.1980' END) AS ultCompra_l1,
    max(CASE sl.id WHEN 2 THEN sl.ultCompra ELSE timestamp'01.01.1980' END) AS ultCompra_l2,
    max(CASE sl.id WHEN 3 THEN sl.ultCompra ELSE timestamp'01.01.1980' END) AS ultCompra_l3,
    max(CASE sl.id WHEN 4 THEN sl.ultCompra ELSE timestamp'01.01.1980' END) AS ultCompra_l4,
    max(CASE sl.id WHEN 5 THEN sl.ultCompra ELSE timestamp'01.01.1980' END) AS ultCompra_l5,
    max(CASE sl.id WHEN 6 THEN sl.ultCompra ELSE timestamp'01.01.1980' END) AS ultCompra_l6,
    max(CASE sl.id WHEN 1 THEN sl.ultForn ELSE '' END) AS ultForn_l1,
    max(CASE sl.id WHEN 2 THEN sl.ultForn ELSE '' END) AS ultForn_l2,
    max(CASE sl.id WHEN 3 THEN sl.ultForn ELSE '' END) AS ultForn_l3,
    max(CASE sl.id WHEN 4 THEN sl.ultForn ELSE '' END) AS ultForn_l4,
    max(CASE sl.id WHEN 5 THEN sl.ultForn ELSE '' END) AS ultForn_l5,
    max(CASE sl.id WHEN 6 THEN sl.ultForn ELSE '' END) AS ultForn_l6,
    max(CASE sl.id WHEN 1 THEN sl.vendas_periodo ELSE 0 END) AS vendas_periodo_l1,
    max(CASE sl.id WHEN 2 THEN sl.vendas_periodo ELSE 0 END) AS vendas_periodo_l2,
    max(CASE sl.id WHEN 3 THEN sl.vendas_periodo ELSE 0 END) AS vendas_periodo_l3,
    max(CASE sl.id WHEN 4 THEN sl.vendas_periodo ELSE 0 END) AS vendas_periodo_l4,
    max(CASE sl.id WHEN 5 THEN sl.vendas_periodo ELSE 0 END) AS vendas_periodo_l5,
    max(CASE sl.id WHEN 6 THEN sl.vendas_periodo ELSE 0 END) AS vendas_periodo_l6,
    max(CASE sl.id WHEN 1 THEN sl.maximo ELSE 0 END) AS maximo_l1,
    max(CASE sl.id WHEN 2 THEN sl.maximo ELSE 0 END) AS maximo_l2,
    max(CASE sl.id WHEN 3 THEN sl.maximo ELSE 0 END) AS maximo_l3,
    max(CASE sl.id WHEN 4 THEN sl.maximo ELSE 0 END) AS maximo_l4,
    max(CASE sl.id WHEN 5 THEN sl.maximo ELSE 0 END) AS maximo_l5,
    max(CASE sl.id WHEN 6 THEN sl.maximo ELSE 0 END) AS maximo_l6,
    max(CASE sl.id WHEN 1 THEN sl.giro ELSE 0 END) AS giro_l1,
    max(CASE sl.id WHEN 2 THEN sl.giro ELSE 0 END) AS giro_l2,
    max(CASE sl.id WHEN 3 THEN sl.giro ELSE 0 END) AS giro_l3,
    max(CASE sl.id WHEN 4 THEN sl.giro ELSE 0 END) AS giro_l4,
    max(CASE sl.id WHEN 5 THEN sl.giro ELSE 0 END) AS giro_l5,
    max(CASE sl.id WHEN 6 THEN sl.giro ELSE 0 END) AS giro_l6,
    max(CASE sl.id WHEN 1 THEN sl.qtde ELSE 0 END) AS qtd_l1,
    max(CASE sl.id WHEN 2 THEN sl.qtde ELSE 0 END) AS qtd_l2,
    max(CASE sl.id WHEN 3 THEN sl.qtde ELSE 0 END) AS qtd_l3,
    max(CASE sl.id WHEN 4 THEN sl.qtde ELSE 0 END) AS qtd_l4,
    max(CASE sl.id WHEN 5 THEN sl.qtde ELSE 0 END) AS qtd_l5,
    max(CASE sl.id WHEN 6 THEN sl.qtde ELSE 0 END) AS qtd_l6,
    max(CASE sl.id WHEN 1 THEN sl.sugestao ELSE 0 END) AS sugestao_l1,
    max(CASE sl.id WHEN 2 THEN sl.sugestao ELSE 0 END) AS sugestao_l2,
    max(CASE sl.id WHEN 3 THEN sl.sugestao ELSE 0 END) AS sugestao_l3,
    max(CASE sl.id WHEN 4 THEN sl.sugestao ELSE 0 END) AS sugestao_l4,
    max(CASE sl.id WHEN 5 THEN sl.sugestao ELSE 0 END) AS sugestao_l5,
    max(CASE sl.id WHEN 6 THEN sl.sugestao ELSE 0 END) AS sugestao_l6
FROM "Grades" gr
INNER JOIN suprimento_loja sl ON sl.grade_id = gr.id
group by gr.id
order by gr.id

“suprimento_loja”视图是函数中以前使用的查询。

不可能这样工作,查询需要1000多秒,函数中的任何更改都不会加快很多速度。所以基本上我需要以另一种方式进行查询?@CaioKeto-Yes。你需要找到另一个解决方案。无论您如何调用该函数,它仍将针对每个
Grades.id
执行。问题出在函数本身。但是如果我在查询中都这么做,它会比函数慢,这个问题有什么好的解决方案吗?因为我需要在函数和join 3中进行计算。@CaioKeto通常函数的速度较慢,而查询速度较慢。特别是当你需要把它和一些东西连接起来的时候。这个函数的作用是什么?你的问题很可能在那里,而不是在你展示给我们的选择中。我将发布函数,但主要是变量。这真的需要有三个(?)光标的函数吗?四个(?)表的联接不能实现相同的功能吗?更正:没有游标,只有聚合。所有内容都可以重写为查询或视图,IMHO。@wildplasser问题是这是每个存储,因此每个存储将有4个连接,而整个select it将有6个存储,因此将有24个连接,这将花费比它所能花费的时间长得多。似乎在这个函数上花费了很多精力。我会尽量把它简化为简单的查询,代码对我来说太程序化了。区别在于它从商店的第一个库存中获取的第一个,但我需要3个库存来进行计算。有什么最好的办法吗?我还在看密码。这看起来太程序化了。我的直觉是,它可以组合成一个查询。我也在尝试创建一个唯一的查询,但我不认为我可以快速返回。我尝试了基于您在这里所做的,创建一个查询来返回我需要的所有内容,但执行它需要花费很多时间,超过1000秒,还没有完成。我的“答案”没有对查询进行任何更改,我只是把它编辑成一个更可读的形式(我可能会犯一些错误,因为我没有数据来测试它)。您的更新似乎再次避免了连接语法和别名,使其再次无法读取。
SELECT 
    gr.id,
    max(CASE sl.id WHEN 1 THEN sl.ultVenda ELSE timestamp'01.01.1980' END) AS ultVenda_l1,
    max(CASE sl.id WHEN 2 THEN sl.ultVenda ELSE timestamp'01.01.1980' END) AS ultVenda_l2,
    max(CASE sl.id WHEN 3 THEN sl.ultVenda ELSE timestamp'01.01.1980' END) AS ultVenda_l3,
    max(CASE sl.id WHEN 4 THEN sl.ultVenda ELSE timestamp'01.01.1980' END) AS ultVenda_l4,
    max(CASE sl.id WHEN 5 THEN sl.ultVenda ELSE timestamp'01.01.1980' END) AS ultVenda_l5,
    max(CASE sl.id WHEN 6 THEN sl.ultVenda ELSE timestamp'01.01.1980' END) AS ultVenda_l6,
    max(CASE sl.id WHEN 1 THEN sl.ultCompra ELSE timestamp'01.01.1980' END) AS ultCompra_l1,
    max(CASE sl.id WHEN 2 THEN sl.ultCompra ELSE timestamp'01.01.1980' END) AS ultCompra_l2,
    max(CASE sl.id WHEN 3 THEN sl.ultCompra ELSE timestamp'01.01.1980' END) AS ultCompra_l3,
    max(CASE sl.id WHEN 4 THEN sl.ultCompra ELSE timestamp'01.01.1980' END) AS ultCompra_l4,
    max(CASE sl.id WHEN 5 THEN sl.ultCompra ELSE timestamp'01.01.1980' END) AS ultCompra_l5,
    max(CASE sl.id WHEN 6 THEN sl.ultCompra ELSE timestamp'01.01.1980' END) AS ultCompra_l6,
    max(CASE sl.id WHEN 1 THEN sl.ultForn ELSE '' END) AS ultForn_l1,
    max(CASE sl.id WHEN 2 THEN sl.ultForn ELSE '' END) AS ultForn_l2,
    max(CASE sl.id WHEN 3 THEN sl.ultForn ELSE '' END) AS ultForn_l3,
    max(CASE sl.id WHEN 4 THEN sl.ultForn ELSE '' END) AS ultForn_l4,
    max(CASE sl.id WHEN 5 THEN sl.ultForn ELSE '' END) AS ultForn_l5,
    max(CASE sl.id WHEN 6 THEN sl.ultForn ELSE '' END) AS ultForn_l6,
    max(CASE sl.id WHEN 1 THEN sl.vendas_periodo ELSE 0 END) AS vendas_periodo_l1,
    max(CASE sl.id WHEN 2 THEN sl.vendas_periodo ELSE 0 END) AS vendas_periodo_l2,
    max(CASE sl.id WHEN 3 THEN sl.vendas_periodo ELSE 0 END) AS vendas_periodo_l3,
    max(CASE sl.id WHEN 4 THEN sl.vendas_periodo ELSE 0 END) AS vendas_periodo_l4,
    max(CASE sl.id WHEN 5 THEN sl.vendas_periodo ELSE 0 END) AS vendas_periodo_l5,
    max(CASE sl.id WHEN 6 THEN sl.vendas_periodo ELSE 0 END) AS vendas_periodo_l6,
    max(CASE sl.id WHEN 1 THEN sl.maximo ELSE 0 END) AS maximo_l1,
    max(CASE sl.id WHEN 2 THEN sl.maximo ELSE 0 END) AS maximo_l2,
    max(CASE sl.id WHEN 3 THEN sl.maximo ELSE 0 END) AS maximo_l3,
    max(CASE sl.id WHEN 4 THEN sl.maximo ELSE 0 END) AS maximo_l4,
    max(CASE sl.id WHEN 5 THEN sl.maximo ELSE 0 END) AS maximo_l5,
    max(CASE sl.id WHEN 6 THEN sl.maximo ELSE 0 END) AS maximo_l6,
    max(CASE sl.id WHEN 1 THEN sl.giro ELSE 0 END) AS giro_l1,
    max(CASE sl.id WHEN 2 THEN sl.giro ELSE 0 END) AS giro_l2,
    max(CASE sl.id WHEN 3 THEN sl.giro ELSE 0 END) AS giro_l3,
    max(CASE sl.id WHEN 4 THEN sl.giro ELSE 0 END) AS giro_l4,
    max(CASE sl.id WHEN 5 THEN sl.giro ELSE 0 END) AS giro_l5,
    max(CASE sl.id WHEN 6 THEN sl.giro ELSE 0 END) AS giro_l6,
    max(CASE sl.id WHEN 1 THEN sl.qtde ELSE 0 END) AS qtd_l1,
    max(CASE sl.id WHEN 2 THEN sl.qtde ELSE 0 END) AS qtd_l2,
    max(CASE sl.id WHEN 3 THEN sl.qtde ELSE 0 END) AS qtd_l3,
    max(CASE sl.id WHEN 4 THEN sl.qtde ELSE 0 END) AS qtd_l4,
    max(CASE sl.id WHEN 5 THEN sl.qtde ELSE 0 END) AS qtd_l5,
    max(CASE sl.id WHEN 6 THEN sl.qtde ELSE 0 END) AS qtd_l6,
    max(CASE sl.id WHEN 1 THEN sl.sugestao ELSE 0 END) AS sugestao_l1,
    max(CASE sl.id WHEN 2 THEN sl.sugestao ELSE 0 END) AS sugestao_l2,
    max(CASE sl.id WHEN 3 THEN sl.sugestao ELSE 0 END) AS sugestao_l3,
    max(CASE sl.id WHEN 4 THEN sl.sugestao ELSE 0 END) AS sugestao_l4,
    max(CASE sl.id WHEN 5 THEN sl.sugestao ELSE 0 END) AS sugestao_l5,
    max(CASE sl.id WHEN 6 THEN sl.sugestao ELSE 0 END) AS sugestao_l6
FROM "Grades" gr
INNER JOIN suprimento_loja sl ON sl.grade_id = gr.id
group by gr.id
order by gr.id