2010-01-06 2 views
6

Lorsque j'écris des requêtes SQL, je me retrouve souvent à penser qu '«il n'y a pas moyen de faire cela avec une seule requête». Quand cela arrive, je me tourne souvent vers des procédures stockées ou des fonctions table à plusieurs instructions qui utilisent des tables temporaires (d'une sorte ou d'une autre) et finissent par simplement combiner les résultats et retourner la table de résultats. Je me demande si quelqu'un sait, en théorie, si devrait être possible d'écrire TOUTES les requêtes qui retournent un ensemble de résultats unique en une seule requête (pas plusieurs instructions). Évidemment, j'ignore les points pertinents tels que la lisibilité du code et la maintenabilité, peut-être même la performance/l'efficacité de la requête. C'est plus sur la théorie - peut-il être fait ... et ne vous inquiétez pas, je ne prévois pas de commencer à forcer moi-même à écrire une requête à une seule instruction quand multi-déclaration répondra mieux à mon but dans tous les cas, mais Cela pourrait me faire réfléchir deux fois ou un peu plus longtemps sur la possibilité d'obtenir le résultat d'une seule requête. Je suppose que quelques paramètres sont en ordre - je pense à une base de données relationnelle (comme MS SQL) avec des tables qui suivent les meilleures pratiques courantes (telles que toutes les tables ayant une clé primaire et ainsi de suite).Question de la théorie SQL Query - requêtes simples ou multi-instructions

Note: (. À partir de documents web ou quelque chose de similaire) afin de gagner « Accepté réponse » à ce sujet, vous devrez fournir une preuve définitive

+0

... ou un contre-exemple. –

+0

Avant de pouvoir répondre à cette question, vous devez être beaucoup plus précis sur ce que vous entendez par "SQL en théorie". Le SQL utilisé dans la pratique varie entre les SGBD et entre les versions de SGBD. Vous devez standardiser sur un ensemble standard de constructions SQL. Par exemple, quels types de sous-requêtes autorisez-vous? En outre, vous pouvez abstraire certains détails, par exemple la «théorie de requête SQL» la plus courante, qui utilise le calcul relationnel ou l'algèbre comme abstraction de SQL, traite les tableaux comme des ensembles de lignes et non comme des listes ordonnées de lignes. – reinierpost

Répondre

2

Au moins avec la version récente d'Oracle est absolument possible. Il a une «clause modèle» qui rend le processus complet. (http://blog.schauderhaft.de/2009/06/18/building-a-turing-engine-in-oracle-sql-using-the-model-clause/). Bien sûr, tout cela avec la limitation habituelle que nous n'avons pas vraiment de temps et de mémoire.

Pour un dialecte sql normal sans ces abdominaux, je ne pense pas que ce soit possible.

Une tâche que je ne vois pas comment mettre en œuvre dans « sql normal » serait: Supposons une table avec une seule colonne de type entier

Pour chaque ligne « prennent la valeur à la ligne actuelle et récupérez autant de lignes, récupérez cette valeur, reprenez autant de lignes, et continuez jusqu'à ce que vous récupériez la même valeur deux fois de suite et que vous la récupériez comme résultat.

+0

Wow très intéressant ... cependant il me semble (si je comprends bien) que bien que ce soit une seule déclaration, ce n'est pas tout à fait dans l'esprit de ma question en ce sens que vous avez la possibilité d'itérer la table des résultats. Je pense que je pensais plutôt à la «théorie des ensembles». Pourtant, le fait que cela atteigne le statut de Turing-complet, et la référence au fait que la plupart des SQL (je suppose que cela implique MSSQL) "ne l'est probablement pas" est assez bon pour une victoire, je pense, même si je Je ne sais toujours pas quelle est la réponse finale à ma «vraie» question. –

3

Je crois qu'il est possible. J'ai travaillé avec des requêtes très difficiles, de très longues requêtes, et souvent, il est possible de le faire avec une seule requête. Mais la plupart du temps, il est plus difficile de le maintenir, donc si vous le faites avec une seule requête, assurez-vous de bien noter votre requête.

Je n'ai jamais rencontré quelque chose qui ne pouvait pas être fait dans une seule requête.
Mais parfois, il est préférable de le faire dans plus d'une requête.

+0

Pour ajouter quelques informations: à mon travail, nous avons des bases de données que la sauvegarde dépasse 60 aller. Nous travaillons avec de très grandes tables et de très grandes données. Pour le type de travail que nous effectuons, les requêtes peuvent traiter plusieurs pages. Il est donc préférable de faire plusieurs requêtes ou d'utiliser des tables de travail. –

+0

Qu'entendez-vous par 'querie do many pages'? –

+0

Je veux dire que lorsque vous l'écrivez dans votre programme (je travaille en C++), vous devez faire défiler plusieurs pages avant d'atteindre la fin de la requête. –

2

Je ne peux pas le prouver, mais je crois que la réponse est un oui prudent - à condition que la conception de votre base de données soit faite correctement. En général, le fait d'être obligé d'écrire plusieurs instructions pour obtenir un certain résultat est un signe que votre schéma peut avoir besoin d'améliorations.

2

Je dirais "oui" mais je ne peux pas le prouver. Cependant, mon principal processus de pensée:

  • Toute sélection doit être une opération ensembliste

  • Votre hypothèse est que vous traitez avec des ensembles mathématiquement correctes (ie normalisée correctement)

  • La théorie des ensembles devrait garantir il est possible

Autres pensées:

  • L'instruction SELECT multiple charge souvent les tables temporaires/variables de table. Ceux-ci peuvent être dérivés ou séparés dans des CTE.

  • Tout traitement RBAR (pour bon ou mauvais) maintenant être traitée CROSS/OUTER APPLY sur les tables dérivées

  • UDFs seraient classés comme « tricherie » dans ce contexte, je me sens, car il vous permet de mettre un SELECT dans un autre module plutôt que dans votre seul

  • n'écrit autorisé dans votre « avant » séquence de DML: cela change l'état de SELECT SELECT

  • Avez-vous vu une partie du code dans notre boutique ?

Modifier, glossaire

Edit: POSTULER: la tricherie?

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

qu'est-ce que rbar, cte et udf? –

+0

Je viens de lire à propos de l'application et cela me semble aussi tricher. Il appelle une fonction qui n'est pas vraiment une entité SQL mais implémentée dans T-SQL, ou quoi que ce soit. –

1

En théorie oui, si vous utilisez des fonctions ou un labyrinthe tortueux d'applications externes ou sous-requêtes; Cependant, pour des raisons de lisibilité et de performance, nous avons toujours utilisé des tables temporaires et des procédures stockées à instructions multiples. Comme quelqu'un l'a commenté ci-dessus, c'est généralement un signe que votre structure de données commence à sentir; pas que c'est mauvais, mais que peut-être il est temps de dénormaliser pour des raisons de performance (arrive aux meilleurs d'entre nous), ou peut-être mettre une couche d'interrogation dénormalisée devant vos données "réelles" normalisées.