Pergunta

Quando eu escrever consultas SQL, encontro-me muitas vezes a pensar que "não há nenhuma maneira de fazer isso com uma única consulta". Quando isso acontece muitas vezes se voltam para procedimentos armazenados ou funções com valor de tabela multi-statement que as mesas uso Temp (de um tipo ou outro) e acabam simplesmente combinando os resultados e retornando tabela de resultados.

Eu estou querendo saber se alguém sabe, simplesmente como uma questão de teoria, se deve ser possível escrever qualquer consulta que retorna um único conjunto de resultados como uma única consulta (não várias instruções). Obviamente, eu estou ignorando pontos relevantes, tais como a legibilidade do código e facilidade de manutenção, talvez até mesmo consulta de desempenho / eficiência. Isso é mais sobre a teoria - que pode ser feito ... e não se preocupe, eu certamente não pretendo começar forçando-me a escrever uma consulta de declaração única quando multi-declaração irá melhor atender o meu propósito em todos os casos, mas ele pode me fazer pensar duas vezes ou um pouco mais sobre se há um caminho viável para obter o resultado de uma única consulta.

Eu acho que alguns parâmetros são em ordem -. Estou pensando em um banco de dados relacional (como MS SQL) com mesas que seguem as melhores práticas comuns (como todas as tabelas com uma chave primária e assim por diante)

Nota: (. Referência ao material web ou algo similar), a fim de ganhar 'aceitado Resposta' sobre isso, você precisará fornecer uma prova definitiva

Foi útil?

Solução

Pelo menos com a uma versão recente do Oracle é absolutamente possível. Ele tem uma 'cláusula modelo' que faz sql turing completa. ( http://blog.schauderhaft.de/2009/06/18/building-a-turing-engine-in-oracle-sql-using-the-model-clause/ ). Claro que isto é tudo com a limitação de costume que nós realmente não temos tempo ilimitado e memória.

Para um dialeto normais sql sem esses abdominations Eu não acho que é possível.

A tarefa que eu não posso ver como implementar em 'sql normal' seria: Assumir uma tabela com uma única coluna de tipo inteiro

Para cada linha 'Tomar o valor na linha atual e ir que muitas fileiras atrás, buscar esse valor, vá que muitas linhas de volta, e continuar até que você buscar o mesmo valor duas vezes consecutivas e retorno que como o resultado.'

Outras dicas

Eu acredito que é possível. Eu já trabalhei com consultas muito difíceis, consultas muito longas, e muitas vezes, é possível fazê-lo com uma única consulta. Mas na maioria das vezes, é mais difícil de mantain, por isso, se você fizer isso com uma única consulta, certifique-se de comentar sua consulta com cuidado.

Eu nunca encontrei algo que não poderia ser feito em uma única consulta.
Mas às vezes é melhor fazê-lo em mais de uma consulta.

Eu não posso provar isso, mas acredito que a resposta é um sim cautelosa - desde seu projeto de banco de dados é feito corretamente. Normalmente sendo forçado a escrever várias instruções para obter um determinado resultado é um sinal de que o esquema pode precisar de algumas melhorias.

Eu diria "sim", mas não pode provar isso. No entanto, a minha principal processo de pensamento:

  • Qualquer seleto deve ser uma operação baseada set

  • O seu pressuposto é que você está lidando com conjuntos matematicamente correta (ou seja normalizada corretamente)

  • A teoria dos conjuntos deve garantir que é possível

Outros pensamentos:

    variáveis ??
  • Multiple instrução SELECT muitas vezes tabelas temporárias de carga / table. Estes podem ser derivados ou separada em CTE.

  • O tratamento RBAR (para o bem ou mal) agora ser tratadas CROSS / EXTERIOR Aplicar em tabelas derivadas

  • UDFs seria classificado como "batota" neste contexto que eu sinto, porque ele permite que você coloque um SELECT em outro módulo, em vez de em seu um único

  • Sem escreve permitidos em seu "antes" seqüência de DML: este muda de estado a partir de Selecionar para selecionar

  • Você já viu algum código em nossa loja?

Editar, glossário

Editar: Aplicar:? Batota

SELECT
    *
FROM
    MyTable1 t1
    CROSS APPLY
    (
        SELECT * FROM MyTable2 t2
        WHERE t1.something = t2.something
    ) t2

Em sim teoria, se você usar funções ou um labirinto tortuoso de EXTERIOR applys ou sub-consultas; No entanto, para facilitar a leitura e desempenho, sempre acabei indo com tabelas temporárias e procedimentos armazenados multi-statement.

Como alguém acima comentou, este é geralmente um sinal de que sua estrutura de dados está começando a cheiro; Não que seja mau , mas que talvez seja hora de denormalise por motivos de desempenho (acontece com o melhor de nós), ou talvez colocar uma camada consultando Desnormaliza na frente de seus dados normalizados "reais".

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top