2010-11-25 18 views
0

Je voudrais appeler une fonction d'agrégat (coût) une fois sur une colonne et la cascader à travers les jointures de gauche (utilisées pour créer une permutation ou une combinaison de lignes). De cette façon, je suppose que le coût est O (n) apposé pour l'appeler après les jointures O (ligne^jointures). À partir de quelque chose comme ceci:Colonne de fonction d'agrégat de passes avec jointure auto-gauche

id | cost 
---------- 
1 | 5 
2 | 10 

Je voudrais faire quelque chose de similaire à ci-dessous. Je peux faire quelque chose de similaire avec une sélection dans une table temporaire et se joindre à ce mais je voudrais éviter d'utiliser une table temporaire ...

CREATE TEMP TABLE tmp_750309_plans AS (SELECT *, cost(id) as cost FROM plans WHERE plans.id IN (1,2,...)); 

SELECT * FROM tmp_750309_plans AS t1 LEFT JOIN tmp_750309_plans AS t2 ON ... 

Je préférerais faire quelque chose comme:

SELECT id, cost(id) as cost FROM plans AS t1 
LEFT JOIN t1 AS t2 
ON t1.id != t2.id 
AND ... 

Pour obtenir quelque chose comme ceci:

id | cost | id | cost | 
----------------------- 
1 | 5 |NULL| NULL | 
2 | 10 |3 | 15 | 

Toute aide serait grandement appréciée.

+0

Que fait la fonction cost()? Vous ne lui donnez aucune contribution. Comment la deuxième colonne de coût serait-elle calculée si la fonction cost() avait des paramètres d'entrée provenant de la table (s)? –

+0

Ok, j'ai mis "id" afin qu'il puisse référencer la ligne. – Moriarty

+0

cost() pourrait être 1 + 1 J'ai juste besoin de savoir comment cascader la colonne à travers les jointures à gauche. Est-ce une sorte de sous-sélection? – Moriarty

Répondre

2

Pas besoin de créer la table temporaire, il suffit de faire votre SELECT une table dérivée:

 
SELECT * 
FROM (
    SELECT *, cost(id) as cost 
    FROM plans 
    WHERE plans.id IN (1,2,...) 
) tmp AS t1 LEFT JOIN tmp AS t2 ON ... 

ou une solution alternative avec une expression de table commune (pour PostgreSQL 8.4 et ci-dessus)

 
with tmp as (
    SELECT *, cost(id) as cost 
    FROM plans 
    WHERE plans.id IN (1,2,...) 
) 
SELECT * 
FROM tmp as T1 
    LEFT JOIN tmp AS t2 ON ... 
+0

Exactement ce dont j'avais besoin! Merci. – Moriarty

+0

Postgresql ne semble pas aimer cette syntaxe mais les bonnes idées. – Moriarty

+0

@Moriarty: quelle syntaxe voulez-vous dire? Pour la deuxième solution, vous aurez besoin au moins de PostgreSQL 8.4. La première solution devrait fonctionner avec n'importe quelle version (au moins> 8.0) –

1

Semble que vous devez utiliser window functions voir this exemple.

Exemple:

SELECT id, sum(cost) OVER (ORDER BY cost) FROM t1; 
+0

Je pensais à ça aussi, mais je n'ai toujours pas compris quelle est la vraie question ... –

+0

Je vais essayer d'en faire usage aujourd'hui. – Moriarty

+0

Merci pour la réponse. Je vais travailler à clarifier la question (comme vous pouvez le constater, j'ai du mal à l'expliquer). – Moriarty