Por que o SQL é BETWEEN inclusivo em vez de meio aberto?

37

Semi-aberto (ou meio aberto, Meio fechado , Half-Bounded ) ( [a,b) , onde x pertence ao intervalo iff a <= x < b ) são bastante comuns na programação, como eles têm muitas propriedades convenientes.

Alguém pode oferecer uma justificativa que explica por que o BETWEEN do SQL usa um intervalo fechado ( [a,b] )? Isso é esp. inconveniente para datas. Por que você teria BETWEEN se comportando assim?

    
por alex 09.08.2012 / 16:57
fonte

4 respostas

43

Acho inclusivo BETWEEN inclusivo é mais intuitivo (e aparentemente, o mesmo fizeram os projetistas SQL) do que um intervalo semi-aberto. Por exemplo, se eu disser "Escolha um número entre 1 e 10", a maioria das pessoas incluirá os números 1 e 10. O intervalo aberto é na verdade particularmente confuso para não desenvolvedores porque é assimétrico. SQL é ocasionalmente usado por não-programadores para fazer consultas simples, e a semântica semiaberta teria sido muito mais confusa para eles.

    
por 09.08.2012 / 17:00
fonte
22

PERGUNTA: Por que o SQL é BETWEEN inclusive?

RESPOSTA: Como os projetistas de linguagem SQL tomaram uma decisão ruim de design, falharam em fornecer a sintaxe que permitiria aos desenvolvedores especificar quais das 4 variantes de BETWEEN (fechada, semi-aberta-esquerda, semi-aberta-direita , ou aberto) eles preferem.

RECOMENDAÇÃO: A menos que o padrão SQL seja alterado, não use BETWEEN para datas / horas. Em vez disso, crie o hábito de codificar as comparações de intervalo DATE como condições independentes nos limites inicial e final do seu intervalo BETWEEN. Isto é um pouco detalhado, mas vai deixar você escrevendo condições que são intuitivas (portanto, menos propensas a serem bugs) e claras para os otimizadores de banco de dados, permitindo que os planos de execução ideais sejam determinados e índices sejam usados.

Por exemplo, se sua consulta está aceitando uma especificação de dia de entrada e deve retornar todos os registros que caíram nessa data, você codificaria como:

  • WHERE DATE_FIELD >= :dt AND DATE_FIELD < :dt+1

Tentar escrever a lógica usando BETWEEN corre o risco de problemas de desempenho e / ou código com bugs. Três erros comuns:

1) WHERE DATE_FIELD BETWEEN :dt AND :dt+1

Este é quase certamente um bug - o usuário espera ver apenas registros para uma data específica, mas um dia terminará com um relatório contendo registros a partir das 12:00 do dia seguinte.

2) WHERE TRUNC(DATE_FIELD) = :dt

Dá resposta correta, mas aplicar a função a DATE_FIELD tornará inútil a maioria das indexações / estatísticas (embora às vezes os DBAs tentem ajudar adicionando índices baseados em função aos campos de data - ainda queimando horas-homem e espaço em disco e adicionando sobrecarga para operações de DIU na mesa)

3) WHERE EVENT_DATE BETWEEN :dt AND :dt + 1-1/24/60/60

Tom Kyte, extraordinário guru da Oracle, recomenda essa solução menos que elegante (IMO). Funciona muito bem até você passar o dia todo descobrindo que "1-1 / 24/06/60" em uma consulta que fornece resultados incompletos ... ou até acidentalmente usá-lo em um campo TIMESTAMP. Além disso, é um pouco proprietário; compatível com o tipo de dados DATE do Oracle (que rastreia até o segundo), mas precisa ser ajustado à precisão DATE / TIME de diferentes produtos de banco de dados.

SOLUÇÃO: Solicite ao comitê SQL do ANSI para aprimorar as especificações da linguagem SQL, modificando a sintaxe BETWEEN para suportar a especificação de alternativas para o padrão CLOSED / INCLUSIVE. Algo assim faria o truque:

expr1 BETWEEN expr2 [ INCL[USIVE] | EXCL[USIVE] ] AND expr3 [ INCL[USIVE] | EXCL[USIVE] ]

Considere como é fácil expressar WHERE DATE_FIELD BETWEEN :dt INCLUSIVE AND :dt+1 EXCLUSIVE (ou apenas WHERE DATE_FIELD BETWEEN :dt AND :dt+1 EXCL )

Talvez ANSI SQL: 2015?

    
por 07.11.2014 / 07:48
fonte
8

Ambos os inclusivos ( a <= x <= b ) e exclusivos ( a < x < b ) são igualmente comuns, por isso, ao fazer os padrões, eles simplesmente tiveram que escolher um. "Entre" em inglês comum é tipicamente inclusivo, e uma instrução SQL deve ser semelhante a uma sentença em inglês, portanto, inclusive era uma escolha sensata.

    
por 09.08.2012 / 17:02
fonte
5

O operador não é chamado de ∩[a,b) , é chamado de BETWEEN , por isso é consideravelmente mais apropriado que sua semântica seja a da frase em inglês "entre" do que a matemática predicado "está em intervalo semi-aberto".

    
por 09.08.2012 / 17:06
fonte

Tags