Testar existência de chave durante query

Forum sobre SQL.

Moderador: Moderadores

Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Testar existência de chave durante query

Mensagem 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?
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"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 do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Testar existência de chave durante query

Mensagem por JoséQuintas »

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 mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"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 do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Testar existência de chave durante query

Mensagem 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
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"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 do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Testar existência de chave durante query

Mensagem 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.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"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 do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Testar existência de chave durante query

Mensagem 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.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Responder