2009-03-10 7 views
0

J'ai une table comme ceci:Rollup colonne pour Sums Normalisé (SQL) - Partie 1

object_id | vote 
1 | 2 
1 | -1 
1 | 5 
2 | 3 
2 | 1 
3 | 4 
3 | -2 

Je veux que ce résultat (pour cet exemple particulier, object_ids 1 et 2 font partie d'un groupe, défini ailleurs , et je suis à la recherche de la normalized_score sorte que la somme = toujours 1. object_id 3 fait partie d'un groupe non utilisé).

object_id | normalized_score 
1 | 6/10 
2 | 4/10 

[ajouté 15:05] 10 ici est la somme des voix pour object_id dans (1,2). Il y a tout un ensemble de logique pour arriver à la (1,2), j'essayais juste de donner la question la plus propre pour que les gens n'aient pas à s'inquiéter de cette partie.

[ajouté 15h10] Comme indiqué dans les commentaires, si le score d'un des objets est inférieur à 0, un problème se pose. Voici la règle, "SI le score pour tout result_id est -x, ET c'est le score minimum pour l'ensemble, AJOUTER x à tous les scores afin de mettre à zéro le score minimum". Je peux le faire pendant mon temps libre en dehors de SQL - donc c'est un bonus seulement si quelqu'un a les cahones pour essayer de le résoudre en SQL.

Si je fais une jointure, je peux obtenir la somme. Je n'arrive pas à comprendre comment obtenir la somme normalisée. Idéalement, cela fonctionnera à la fois dans MySQL 5.x et Sqlite3. Sinon, je peux le faire avec deux requêtes distinctes et faire le travail en post-traitement.

+0

Où le «10» entre-t-il dans les choses ici? –

+0

Si le vote est censé être sur 10 alors comment pouvez-vous permettre des votes négatifs? –

+0

Je suis désolé 10 est la somme des votes où object_id dans (1,2). Je vais mettre à jour la question –

Répondre

1

La solution sans compenser les votes négatifs (j'inclure celui-ci parce que son beaucoup plus facile à lire/comprendre):

SELECT object_id 
,  SUM(vote) + '/' + total AS normalized_score 
FROM tabel 
,  (
     SELECT sum(vote) AS total 
     FROM tabel 
     ) 
GROUP BY object_id, total 

Solution complète:

SELECT object_id 
,  SUM(vote + minvote) + '/' + (total + minvote * count) AS normalized_score 
FROM tabel 
,  (
     SELECT sum(vote) AS total 
     ,  CASE WHEN MIN(vote) < 0 THEN 
        -MIN(vote) 
       END AS minvote 
     ,  COUNT(*) AS count 
     FROM tabel 
     ) 
GROUP BY object_id, total, minvote, count 

(Je ne J'ai accès à MySQL, j'ai donc écrit une requête dans Oracle et remplacé || par +. J'espère que cela fonctionne en MySQL ou du moins aide :))

+0

Ouais - Je pensais qu'une sous-requête était nécessaire. J'essaie généralement d'éviter cela, et je suis sûr qu'il existe une solution non sous-requête, mais cela devrait être assez bon pour moins de quelques centaines de milliers d'enregistrements - ce qui est bien pour le moment. Merci pour votre réponse –

1

Les commentaires sont tout à fait corrects .. mais je ferai l'hypothèse que 10 est juste un certain nombre que vous avez choisi de votre ... nez.

SELECT object_id ObjectID, SUM (vote) + '/ 10' AS NormalizedVote FROM table GROUP BY object_id

Profitez.

+0

Je suis désolé, je n'étais pas clair. '10' est la somme de tous les autres votes dans ce groupe - sinon ce serait une question triviale. Je vais mettre à jour la question. –

1
 
-- SQL solution 
SELECT 
    object_id AS ObjectID, 
    (SUM(CASE SIGN(vote) WHEN 1 THEN vote ELSE 0 END) - 
    ((CASE SIGN(MIN(vote)) WHEN -1 THEN MIN(vote) ELSE 0) * 
    (COUNT(1)))) + '/10' AS NormalizedVote 
FROM table 
GROUP BY object_id 
+0

Similairement à celui que j'ai marqué comme réponse (bien que celui-là soit réparable), le SUM() inclut les votes pour object_id = 3, ce qui ne fonctionnera pas. J'aime bien qu'il n'y ait pas de sous-requête - merci pour l'entrée. –

Questions connexes