Página 1 de 1

Testar existência de chave durante query

Enviado: 06 Set 2021 09:10
por JoséQuintas
Preciso testar se um produto existe numa determinada tabela, mas a tabela contém vários registros para um mesmo produto.
O resultado disso vai ser usado como referência na própria query.
Por enquanto minha alternativa foi um sub-select trazendo uma única linha.

Código: Selecionar todos

SELECT IDPRODUTO, IF( X.PCPRODUTO IS NULL, 1.03, 1.04 ) * VALOR1, IF( X.PCPRODUTO IS NULL, 1.03, 1.04) * VALOR2
LEFT JOIN ( SELECT PCPRODUTO FROM JPPRECO WHERE PCPRODUTO = nIdProduto LIMIT 1) AS X ON X.PCPRODUTO = IDPRODUTO
WHERE IDPRODUTO = nIdProduto
O EXISTS depende de comando SQL, o que deixaria isso muito mais longo.
COUNT(*) dependeria de um GROUP BY
Tem algum JOIN que retorne apenas uma linha ou nenhuma?

Testar existência de chave durante query

Enviado: 06 Set 2021 10:37
por JoséQuintas
Ainda não resolvi.
Isso não funciona em terminal service remoto, o que é muito estranho.

Testar existência de chave durante query

Enviado: 06 Set 2021 12:57
por JoséQuintas
existe.png
Não vai de um jeito, vai de outro.... rs

Código: Selecionar todos

               :cSQL := "SELECT D.*," + ;
                  " ( 100 + PERCENTUALA ) / 100 * PRECOBASE AS TABA," + ;
                  " ( 100 + PERCENTUALB ) / 100 * PRECOBASE AS TABB," + ;
                  " ( 100 + PERCENTUALC ) / 100 * PRECOBASE AS TABC," + ;
                  " ( 100 + PERCENTUALD ) / 100 * PRECOBASE AS TABD," + ;
                  " ( 100 + PERCENTUALE ) / 100 * PRECOBASE AS TABE," + ;
                  " ( 100 + PERCENTUALF ) / 100 * PRECOBASE AS TABF" + ;
                  " FROM (" + ;
                  " SELECT IDPRODUTO, IEPRODEP, IEVALCUS, IECUSCON, IEULTPRE, " + ;
                  " GREATEST( IEVALCUS, IECUSCON * X.MARGEM," + ;
                  " IEULTPRE * X.MARGEM ) AS PRECOBASE," + ;
                  " COALESCE( A.PERCA, B.PERCA, C.PERCA, 0 ) AS PERCENTUALA," + ;
                  " COALESCE( A.PERCB, B.PERCB, C.PERCB, 0 ) AS PERCENTUALB," + ;
                  " COALESCE( A.PERCC, B.PERCC, C.PERCC, 0 ) AS PERCENTUALC," + ;
                  " COALESCE( A.PERCD, B.PERCD, C.PERCD, 0 ) AS PERCENTUALD," + ;
                  " COALESCE( A.PERCE, B.PERCE, C.PERCE, 0 ) AS PERCENTUALE," + ;
                  " COALESCE( A.PERCF, B.PERCF, C.PERCF, 0 ) AS PERCENTUALF" + ;
                  " FROM JPITEM" + ;
                  " LEFT JOIN JPTABPRODEP ON IDPRODEP = IEPRODEP" + ;
                  " LEFT JOIN JPTABPROSEC ON IDPROSEC = IEPROSEC" + ;
                  " LEFT JOIN JPTABPROGRU ON IDPROGRU = IEPROGRU" + ;
                  " LEFT JOIN JPTABPERCENTUAL AS A ON A.PERCPRODUTO = IDPRODUTO" + ;
                  " LEFT JOIN JPTABPERCENTUAL AS B ON B.PERCPRODEP = IEPRODEP" + ;
                  " LEFT JOIN JPTABPERCENTUAL AS C ON C.PERCPRODEP = 0 AND C.PERCPRODUTO = 0" + ;
                  " JOIN ( SELECT IF( EXISTS ( SELECT DISTINCT PCPRODUTO FROM JPPRECO WHERE PCPRODUTO=" + ;
                      NumberSQL( nIdProduto ) + "), 1.03, 1.04 ) AS MARGEM ) AS X" + ;
                  " WHERE IDPRODUTO = " + NumberSQL( nIdProduto ) + " ) AS D"
Pra que complicar kkkkkkk

Testar existência de chave durante query

Enviado: 06 Set 2021 13:07
por JoséQuintas
Talvez aqui fique melhor de entender:

disto

Código: Selecionar todos

      WITH OBJECT cnSQL
         :cSQL := "UPDATE JPITEM " + ;
            " LEFT JOIN JPPRECO ON PCPRODUTO = IDPRODUTO" + ;
            " SET" + ;
            "IECUSCON = " + NumberSQL( mieCusCon ) + "," + ;
            " IEVALOR = GREATEST( " + NumberSQL( mieCusCon ) + ", " + ;
               " ROUND( IEULTPRE * IF( JPPRECO.PCPRODUTO IS NULL, 1.04, 1.03 ), 2 )," + ;
               " ROUND( IEVALOR  * IF( JPPRECO.PCPRODUTO IS NULL, 1.04, 1.03 ), 2 ) )" + ;
            " WHERE IDPRODUTO = " + NumberSQL( nIdProduto ) + ;
            " LIMIT 1"
         :ExecuteCmd()
      ENDWITH
pra isto

Código: Selecionar todos

      WITH OBJECT cnSQL
         :cSQL := "UPDATE JPITEM " + ;
            " JOIN " + ;
            " ( SELECT IF( EXISTS ( SELECT DISTINCT PCPRODUTO FROM JPPRECO WHERE IDPRODUTO=" + ;
               NumberSQL( nIdProduto ) + " ), 1.03, 1.04 ) AS MARGEM ) AS X" + ;
            " SET" + ;
            "IECUSCON = " + NumberSQL( mieCusCon ) + "," + ;
            " IEVALOR = GREATEST( " + NumberSQL( mieCusCon ) + ", " + ;
               " ROUND( IEULTPRE * X.MARGEM, 2 )," + ;
               " ROUND( IEVALOR  * X.MARGEM, 2 ) )" + ;
            " WHERE IDPRODUTO = " + NumberSQL( nIdProduto ) 
         :ExecuteCmd()
      ENDWITH
Basicamente é aplicar 1.03 ou 1.04 como margem, caso exista em JPPRECO ou não.

O SELECT mais interno faz esse trabalho: Uma tabela X com 1 registro, com o campo MARGEM, preenchido conforme existe ou não.
O externo, com JOIN, apenas usa X.MARGEM.
Dependendo do ponto de vista, simplificou.

Testar existência de chave durante query

Enviado: 06 Set 2021 13:28
por JoséQuintas
ou... sei lá se é abusar...

Código: Selecionar todos

CREATE FUNCTION ze_MargemLucro( nIdProduto INT(11) )
RETURNS DECIMAL(16,5)

BEGIN

DECLARE nFound INT(11);
DECLARE nMargem DECIMAL(16,5);

SET nFound := EXISTS ( SELECT PCPRODUTO FROM JPPRECO WHERE PCPRODUTO = nIdProduto LIMIT 1 );
SET nMargem := IF( nFound, 1.03, 1.04 );

RETURN nMargem;

END
agora dá pra usar:

Código: Selecionar todos

SELECT IDPRODUTO, ze_MargemLucro( IDPRODUTO ) FROM JPITEM
margem.png
Sei lá se isso é abusar do servidor.
Só sei que os comandos ficam mais simples.