2009-03-10 2 views
0

У меня есть таблица, например, так:Rollup Колонка для нормированных сумм (SQL) - Часть 1

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

Я хочу этот результат (в данном конкретном примере, object_ids 1 и 2 являются частью группы, определенные в другом месте и я ищу для normalized_score так, чтобы сумма всегда = 1 object_ID 3 является частью неиспользованной группы):.

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

[добавлено 3:05 PM] 10 вот сумма голосов за object_id в (1,2). Есть еще один набор логики, чтобы придумать (1,2), я просто пытался дать самый чистый вопрос, чтобы людям не пришлось беспокоиться об этой части.

[добавлено 15:10] Как указано в комментариях, если оценка для одного из объектов ниже 0, возникает проблема. Вот правило: «Если оценка для любого result_id равна -x, И это минимальный балл для набора, ADD x для всех оценок, чтобы обнулить минимальный балл». Я могу сделать это в свое время, хотя вне SQL - так что это бонус только в том случае, если у кого-то есть cahones, чтобы попытаться решить его в SQL.

Если я сам присоединяюсь, я могу получить сумму. Я не могу понять, как получить нормализованную сумму. В идеале это будет работать как в MySQL 5.x, так и в Sqlite3. В противном случае я могу сделать это с двумя отдельными запросами и просто выполнить работу по последующей обработке.

+0

Где здесь «10»? –

+0

Если голосование должно быть из 10, то как вы можете разрешить отрицательные голоса? –

+0

Простите, что 10 - это сумма голосов, где object_id в (1,2). Я обновлю вопрос –

ответ

1

Решение без компенсации негативных голосов (я включаю этот, потому что его гораздо легче читать/понимать):

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

Полное решение:

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 

(я не» t иметь доступ к MySQL, поэтому я написал запрос в Oracle и заменил || на +. Надеюсь, он работает в MySQL или, по крайней мере, помогает :))

+0

Да, я думал, что необходим подзапрос. Обычно я стараюсь их избегать, и я уверен, что есть решение без подзапроса, но это должно быть достаточно хорошо для менее чем нескольких сотен тысяч записей, что сейчас прекрасно. Спасибо за отличный ответ. –

1

Замечания совершенно правильные .. но я сделаю предположение, что 10 - это просто номер, который вы выбрали из своего ... носа.

ВЫБОР object_id КАК ObjectID, СУММА (голос) +/10 'КАК NormalizedVote ОТ таблицы GROUP BY object_id

Наслаждайтесь.

+0

Простите, я не был ясен. «10» - это сумма всех остальных голосов в этой группе, иначе это был бы тривиальный вопрос. Я уточню вопрос. –

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

Аналогично тому, который я обозначил как ответ (хотя этот исправляемый), SUM() включает в себя голоса за object_id = 3, которые не будут работать. Мне нравится, что нет подзапроса, хотя - спасибо за ввод. –

Смежные вопросы