Clipper On Line • Ver Tópico - Testar existência de chave durante query

Testar existência de chave durante query

Discussão sobre SQL

Moderador: Moderadores

 

Testar existência de chave durante query

Mensagempor JoséQuintas » 06 Set 2021 09:10

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.

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?
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18014
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Testar existência de chave durante query

Mensagempor JoséQuintas » 06 Set 2021 10:37

Ainda não resolvi.
Isso não funciona em terminal service remoto, o que é muito estranho.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18014
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Testar existência de chave durante query

Mensagempor JoséQuintas » 06 Set 2021 12:57

existe.png


Não vai de um jeito, vai de outro.... rs

               :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
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18014
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Testar existência de chave durante query

Mensagempor JoséQuintas » 06 Set 2021 13:07

Talvez aqui fique melhor de entender:

disto

      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

      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.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18014
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Testar existência de chave durante query

Mensagempor JoséQuintas » 06 Set 2021 13:28

ou... sei lá se é abusar...

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:

SELECT IDPRODUTO, ze_MargemLucro( IDPRODUTO ) FROM JPITEM


margem.png


Sei lá se isso é abusar do servidor.
Só sei que os comandos ficam mais simples.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18014
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes




Retornar para SQL

Quem está online

Usuários vendo este fórum: Nenhum usuário registrado online e 7 visitantes


Ola Amigo, espero que meu site e forum tem lhe beneficiado, com exemplos e dicas de programacao.
Entao divulgue o link da Doacao abaixo para seus amigos e redes sociais ou faça uma doacao para o site forum...
MUITO OBRIGADO PELA SUA DOACAO!
Faça uma doação para o forum
cron
v
Olá visitante, seja bem-vindo ao Fórum Clipper On Line!
Efetue o seu login ou faça o seu Registro