2009-03-10 3 views
0

Ich habe eine Tabelle wie folgt:Rollup Spalte für Normalized Sums (SQL) - Teil 1

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

ich dieses Ergebnis will (für dieses Beispiel, object_ids 1 und 2 sind Teil einer Gruppe, die an anderer Stelle und ich bin auf der Suche für die normalized_score so dass die Summe immer 1. object_id 3 = Teil einer ungenutzten Gruppe ist.):

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

[hinzugefügt 3.05] 10 ist hier die Summe der Stimmen für object_id in (1,2). Es gibt eine ganz andere Logik, um mit der (1,2) zu kommen, ich habe nur versucht, die sauberste Frage zu stellen, so dass die Leute sich nicht um diesen Teil kümmern müssen.

[hinzugefügt 3:10 PM] Wie in den Kommentaren darauf hingewiesen, wenn das Ergebnis für eines der Objekte unter 0 ist, entsteht ein Problem. Hier ist die Regel: "Wenn die Punktzahl für eine Ergebnis-ID -x ist, UND das ist die Mindestpunktzahl für die Menge, ADD X zu allen Punkten, um die Mindestpunktzahl Null". Ich kann dies zu meiner Zeit außerhalb von SQL tun - also ist es nur ein Bonus, wenn jemand die Cahones hat, um es in SQL zu versuchen.

Wenn ich einen Selbstbeitritt mache, kann ich die Summe bekommen. Ich kann nicht herausfinden, wie man die normalisierte Summe bekommt. Idealerweise funktioniert dies sowohl in MySQL 5.x als auch in Sqlite3. Ansonsten kann ich das mit zwei getrennten Abfragen machen und die Arbeit einfach in der Nachbearbeitung erledigen.

+0

Wo kommen die "10" her? –

+0

Wenn die Abstimmung 10 sein soll, wie können Sie dann negative Stimmen zulassen? –

+0

Es tut mir leid 10 ist die Summe der Stimmen wo object_id in (1,2). Ich werde die Frage aktualisieren –

Antwort

1

Die Lösung ohne negative Stimmen Kompensation (I um diesen einen, weil seine viel einfacher zu lesen/verstehen):

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

Voll Lösung:

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 

(I don‘ t habe Zugriff auf MySQL, also schrieb ich eine Abfrage in Oracle und ersetzte || für +. Hoffe, es funktioniert in MySQL oder hilft zumindest :))

+0

Ja - ich dachte, eine Unterabfrage sei notwendig. Normalerweise versuche ich, diese zu vermeiden, und ich bin mir sicher, dass es eine Lösung ohne Unterabfrage gibt, aber das sollte für weniger als ein paar hunderttausend Datensätze gut genug sein - was für den Moment in Ordnung ist. Danke für eine tolle Antwort. –

1

Die Kommentare sind ziemlich korrekt .. aber ich werde die Annahme machen, dass 10 nur eine Nummer ist, die Sie aus Ihrer ... Nase herausgesucht haben.

SELECT Object_id AS ObjektID, SUM (Abstimmung) + '/ 10' AS NormalizedVote FROM Tabelle GROUP BY Object_id

genießen.

+0

Es tut mir leid, ich war nicht klar. "10" ist die Summe aller anderen Stimmen in dieser Gruppe - sonst wäre das eine triviale Frage. Ich werde die Frage aktualisieren. –

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

Ähnlich wie die, die ich als Antwort markiert habe (obwohl diese fixierbar ist), enthält SUM() die Votes für object_id = 3, die nicht funktionieren. Mir gefällt, dass es keine Unterabfrage gibt - danke für die Eingabe. –