2010-07-12 7 views
2

Je dois appliquer deux fonctions d'agrégat successives à un ensemble de données (la somme d'une série de moyennes), ce qui est facile et routinier avec les expressions de table communes dans SQL Server ou un autre SGBD prenant en charge les CTE . Malheureusement, je suis actuellement bloqué avec SQLite qui ne supporte pas les CTE. Existe-t-il une alternative ou une solution de contournement permettant d'obtenir le même résultat dans SQLite sans effectuer deux requêtes et en regroupant les résultats dans le code? Pour ajouter un peu plus de détails, je ne pense pas que cela puisse être facilement fait avec les vues car le premier ensemble de valeurs d'agrégat doit être récupéré sur la base d'une clause WHERE avec plusieurs paramètres. Par exemple,Fonctionnalité d'expression de table commune dans SQLite

SELECT avg(elapsedTime) 
FROM statisticsTable 
WHERE connectionId in ([lots of values]) AND 
     updateTime > [startTime] AND 
     updateTime < [endTime] 
GROUP BY connectionId 

Et puis j'ai besoin de la somme de ces moyennes.

+0

j'ai ajouté une autre réponse que (je crois) permet de résoudre ce problème sans utiliser CTE. –

+0

Après avoir examiné certaines des autres questions que vous avez posées sur SO, je crois qu'ils peuvent être résolus en utilisant une sous-requête ou une technique de vue en ligne. À titre d'exercice, vous pouvez essayer de réécrire ces requêtes sans CTE. Bien que je ne suggère pas de laisser ces nouvelles requêtes dans votre code de production, il pourrait être utile d'apprendre une nouvelle technique pour résoudre des problèmes similaires dans des SGBDR moins complets. –

+4

Les CTE viennent d'être ajoutés à SQLite. http://www.sqlite.org/lang_with.html – schlenk

Répondre

3

Est-ce que cela fonctionnerait?

SELECT SUM(t.time) as sum_of_series_of_averages 
FROM 
(
SELECT avg(elapsedTime) as time 
FROM statisticsTable 
WHERE connectionId in ([lots of values]) AND 
     updateTime > [startTime] AND 
     updateTime < [endTime] 
GROUP BY connectionId 
) as t 

En convertissant vos moyennes dans une vue en ligne, vous pouvez SUM() les moyennes.

Est-ce ce que vous cherchez?

+0

NB: Vous pouvez également remplacer vos [lots de valeurs] par une autre requête de résultat à colonne unique. –

+0

J'ai remarqué dans certaines de vos autres questions que vous deviez renvoyer un résultat comme celui-ci en tant que valeur dans l'une des colonnes du résultat. Si tel est le cas, convertissez cette requête en sous-requête dans la clause SELECT.Si vous avez besoin d'un exemple dans ma réponse, s'il vous plaît faites le moi savoir. –

+0

Oui, merci. Cela fonctionne. Je suis un peu flou sur la gamme des utilisations possibles pour les sous-requêtes, donc je vais devoir lire sur eux car ce n'est évidemment pas une application particulièrement complexe d'entre eux. – Dan

2

Comme vous l'avez mentionné, SQLite ne prend pas en charge les CTE, les fonctions de fenêtre ou autres.

Vous pouvez cependant écrire vos propres fonctions utilisateur que vous pouvez appeler dans SQLite en les enregistrant dans la base de données avec l'API SQLite en utilisant sqlite_create_function(). Vous les enregistrez dans la base de données, et vous pouvez ensuite les utiliser dans votre propre code d'application. Vous pouvez créer une fonction agrégée qui effectue la somme d'une série de moyennes en fonction des valeurs de colonnes individuelles. Pour chaque valeur, une fonction de rappel en mode pas à pas est appelée, vous permettant d'effectuer un calcul sur les données, et un pointeur pour la conservation des données d'état est également disponible.

Dans votre SQL, puis, vous pouvez enregistrer une fonction personnalisée appelée sum_of_series_of_averages et ont:

SELECT sum_of_series_of_averages(columnA,columnB) 
FROM table 
WHERE ... 

Pour quelques bons exemples sur la façon dont les travaux, vous devriez vérifier le code source SQLite, et vérifier aussi this tutorial (recherchez Defining SQLite User Functions).

+0

Merci, j'ai ajouté quelques détails à ma question originale. – Dan

+0

Je parlais en général; merci d'avoir ajouté des détails. –

7

Maintenant que nous sommes dans le futur, permettez-moi de noter ici que SQLite maintenant prend en charge prend en charge les expressions de table communes, à partir de la version 3.8.3 du 2014-02-03.

http://www.sqlite.org/lang_with.html

+0

Avez-vous une référence? – SysDragon

+0

@SysDragon: Que diriez-vous de la [documentation sur les CTE] (http://www.sqlite.org/lang_with.html). – Cameron

+0

@Cameron Merci – SysDragon

Questions connexes