2008-11-11 6 views
3

J'ai une clause group by dans une instruction sql et j'ai besoin d'utiliser une fonction d'agrégat pour réduire toutes les valeurs de chaque groupe au lieu d'ajouter comme Sum() fonction.Comment faire pour moins au lieu d'ajouter une fonction Sum() comme sql

dire

SELECT Sum(A) 
FROM ( 
    SELECT 2 AS A 
    UNION 
    SELECT 1) AS t1 

..so évaluera 2 + 1 et de retour 3.

J'ai besoin d'une certaine façon de faire 2-1 pour revenir 1.

Hope this sens. La seule façon de le faire serait d'utiliser l'intégration CLR pour créer ma propre fonction d'agrégat.

D'autres idées?

+0

Ne serait-ce toujours évaluer à zéro? – FlySwat

+0

2-1 serait égal à 1 non nul. – HAdes

+0

Dans votre exemple artificiel oui, mais lorsque vous regroupez de grandes quantités de données, je ne vois pas ce que vous essayez de faire. – FlySwat

Répondre

2

Comment allez-vous identifier l'objet à soustraire?

Une fois identifié, il s'agit d'un SUM() multiplié par -1, puis ajouté à cette valeur.

Edit:

Si elle est la première valeur à prendre comme soustraites de prendre ensuite cette valeur, doubler, puis prendre loin la somme de toutes les valeurs. (Doubler il annule l'effet de l'inclure dans la somme de toutes les valeurs.)

select top 1 @var = [value] 
from myTable 
order by [some condition] 

select @minused = (2 * @var) - sum([value]) 
from myTable 
+0

Pas besoin d'identifier quoi que ce soit. Je veux simplement prendre la première valeur et continuer à enlever tout le reste. i.e 2-1-1-2-3 ... etc etc Ensuite, j'ai mon résultat et peut l'absolu pour obtenir la différence. – HAdes

+0

HAdes, je crois qu'il fait ce que vous vouliez. – kristof

0

SOMME() fonctionne, comme 2 + 1 == 1 + 2, alors que 2-1! = 1-2 , donc une telle fonction produirait des résultats différents lorsque le ORDER BY change, s'il devait exister.

+0

Je comprends cela, mais je vais absolument absolut la réponse de toute façon. donc abs (2-1) est identique à abs (1-2). Désolé je ne pensais pas que je devrais mentionner cela. – HAdes

+0

Cela fonctionne pour deux valeurs. Pour plus, vous pouvez obtenir des abdos (1-2-3)! = Abs (3-2-1). – che

0

Je ne sais pas pourquoi vous voudriez, mais je venais de sommer les valeurs négatives des données renvoyées:

SELECT Sum(A) 
FROM ( 
    SELECT (2 * -1) AS A 
    UNION 
    SELECT (1)) AS t1 
+0

Mon exemple était à des fins de démonstration. En fait, je ne fais pas de syndicat. Il suffit de sélectionner sum (A) à partir de tableA afin que vous ne pouvez pas annuler l'une des lignes comme vous le suggérez. – HAdes

2

A partir de votre question, il ne sait pas exactement ce que vous voulez faire. Si vous voulez que la somme de toutes les valeurs soit négative, vous pouvez simplement faire un SUM(), et multiplier par -1 pour retourner un résultat négatif.

Dans votre exemple, il semble que vous vouliez obtenir la somme de la première ligne de la table, moins toutes les autres valeurs. Donc si vous aviez les valeurs 10, 15, 5, 20 vous voudriez: 10 - 15 - 5 - 20. Cette valeur est la même que 10 - (15 + 5 + 20). Vous pouvez obtenir la première ligne dans une table en utilisant LIMIT. Nous allons également besoin de la clé primaire pour la prochaine étape:

SELECT primary_key AS pk, field FROM table LIMIT 1; 

Nous pouvons obtenir la somme de toutes les autres lignes en excluant ce qui précède celui-ci:

SELECT SUM(field) FROM table WHERE primary_key != pk; 

Vous pouvez ensuite soustraire la deuxième valeur Depuis le premier.

2

lire vos commentaires, je pense que vous voulez quelque chose comme ceci:

SELECT SUM(CASE WHEN ROWNUM=1 THEN 2*A ELSE -A END) 
FROM foo 

Bien que pour obtenir la commande fiable, vous allez probablement avoir besoin d'utiliser un autre sélectionnez:

SELECT SUM(b) 
FROM (
    SELECT CASE WHEN ROWNUM=1 THEN 2*a ELSE -a END AS b 
    FROM foo 
    ORDER BY ??? 
); 
+0

vient de remarquer que c'était une question SQL Server - je pensais que je regardais les questions Oracle. Je vais laisser ma réponse au cas où cela vous aiderait. –

Questions connexes