TransWikia.com

Existe alguma diferença nessas duas querys?

Stack Overflow em Português Asked on December 14, 2021

Existe alguma diferença nessas duas querys? Qual a diferença de se utilizar o parenteses no and?

SELECT *
FROM produto
WHERE grupo = 'bebidas'
AND preco < 10 OR estoque <= 100
ORDER BY estoque DESC;

SELECT *
FROM PRODUTO
WHERE grupo = 'bebidas'
AND (preco < 10 OR estoque <= 100)
ORDER BY estoque DESC;

4 Answers

Eu tenho visto muitos SELECTs e IFs dentro da programação, e confesso que fico pensando como a pessoa faz pra manter o código coeso... claro que um pouco de atenção ajuda, mas a utilização de "()" não vai cair sua mão e no meu ponto de vista deixa a programação muito mais organizada.

Exemplo sem ():

SELECT * FROM TABELA WHERE CAMPO_A >= VALOR AND CAMPO_B <= VALOR AND STATUS = 'A'

Com ()

SELECT * FROM TABELA WHERE (CAMPO_A >= VALOR) AND (CAMPO_B <= VALOR) AND (STATUS = 'A')

Agora veja um exemplo onde você pode ter um erro pela falta de ()

SELECT * FROM TABELA A
WHERE CAMPO <= B.VALOR * C.VALOR - D.VALOR
INNER JOIN TABELA_B B ON(B.CODIGO = A.CODIGO)
INNER JOIN TABELA_C C ON(C.CODIGO = A.CODIGO)
INNER JOIN TABELA_D D ON(D.CODIGO = A.CODIGO)

Sabemos que a multiplicação será executada primeiro, mas e se você quisesse primeiro a subtração?

Para você não ter que reescrever todo o código é só usar ()

SELECT * FROM TABELA A
WHERE CAMPO <= B.VALOR * (C.VALOR - D.VALOR)
INNER JOIN TABELA_B B ON(B.CODIGO = A.CODIGO)
INNER JOIN TABELA_C C ON(C.CODIGO = A.CODIGO)
INNER JOIN TABELA_D D ON(D.CODIGO = A.CODIGO)

O uso de () não é só questão de visualização, ele é muito importante e deve ser levado em conta

2 * 1 - 1 

É diferente de

2 * (1 - 1) 

Answered by Marcelo on December 14, 2021

Muita diferença. Quando colocamos um parenteses, tudo o que está dentro dele será considerado apenas um resultado. No seu exemplo, o primeiro select tem TRÊS condições INDIVIDUAIS: ele trará todos os registros que pertencerem ao grupo 'bebidas', o preço for menor que 10 OU (atenção ao 'ou') estoque menor/igual a 100. Se existir um produto com grupo 'comidas' e estoque igual a 9, ele irá aparecer porque a última condição foi satisfeita. Já o segundo select tem DUAS condições: pertencer ao grupo 'bebidas' e possuir uma das características mencionadas no parenteses, já que o 'ou' agora pertence à expressão interna. A primeira condição não é negociável. Somente produtos pertencentes ao grupo 'bebidas' serão relacionados se possuírem preço ou estoque de acordo com o filtro. Aquele produto do grupo 'comidas' não apareceria no segundo select.

Answered by Lisângelo Berti on December 14, 2021

É uma questão de precedência e associatividade de operadores. Quando usa uma expressão composta de AND e OR, ou seja, de operadores relacionais, que são aqueles que avaliam valores "binários" e geram novos de acordo a álgebra booleana (veja tabela verdade e mapa de Karnaugh).

O AND é como se fosse uma multiplicação e o OR é como se fosse uma adição, então sem parênteses que mude esta precedência, o que está próximo do AND é usado prioritariamente em detrimento do que está próximo do OR.

Então leia os códigos assim para entender melhor:

(grupo = 'bebidas' AND preco < 10) OR estoque <= 100
grupo = 'bebidas' AND (preco < 10 OR estoque <= 100)

Como o AND tem precedência natural definida pela linguagem os parênteses não são necessários no primeiro, mas obrigatórios no segundo para dar a semântica pretendida nela.

De fato há quem diga, e eu concordo, que para estes operadores sempre deveria usar os parênteses para deixar claro e explícito qual é a intenção e evitar enganos sem querer. Há quem diga que deveria fazer para todos os operadores, mas isto seria exagerado, alguma não menos intuitivos que outros para um humano "normal".

Para tentar fazer uma leitura do que é cada expressão, que nosso amigo tentou mas ficou muito confuso, por isso devem ter negativado:

  1. Tudo que seja do GRUPO de "bebidas" E ao mesmo tempo tenha PREÇO inferior à 10. Mas se esta condição não for atendida, pode pegar um produto que tenha o estoque igual ou inferior à 100, portanto se algo tiver estoque abaixo desse limite conta como alfo a ser considerado na seleção, não importa de que grupo pertence ou qual é o preço. O que me parece bem incoerente e parece um erro.

  2. Tudo que seja do GRUPO de "bebidas" E cumpra pelo menos uma das duas condições a seguir: tenha PREÇO inferior à 10 OU tenha o estoque igual ou inferior à 100. neste caso ser do grupo "bebida" passa ser obrigatório para todos. O que também parece errado, mas quem sou eu para falar sem saber qual é o problema. Tem cara que deveria ser tudo válido e aí deveria ter 2 AND, o que dispensaria parênteses, embora possa colocar para deixar mais legível, ainda que neste caso mude pouco.

Outra questão de legibilidade é que ficou pouco visível onde é cada cláusula, seria melhor colocar o WHERE em uma linha só ou indentar:

SELECT *
FROM PRODUTO
WHERE grupo = 'bebidas' AND
    (preco < 10 OR estoque <= 100)
ORDER BY estoque DESC;

Coloquei no GitHub para referência futura.

Answered by Maniero on December 14, 2021

Bom falando sobre o from, poderá ter diferença se o Case-sensitive (é um anglicismo que se refere a um tipo de análise tipográfica da informática. Em língua portuguesa, significa algo como "sensível à caixa das letras" ou "sensível a maiúsculas e minúsculas") estiver habilitar no DB (Banco de Dados). Caso contrario as duas tera o mesmo resultado. Sobre o where pode ter diferenças no resultado final pois a primeira vc esta colocando o condicional como "grupo = 'bebidas' AND preco < 10" sendo verdade ou "estoque <= 100" verdade, para a segunda vc esta colocando o condicional como "grupo = 'bebidas'" verdade e "preco < 10" verdade ou "estoque <= 100".

:)

Answered by H. Ricardo on December 14, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP