2013-11-14 2 views
2

Либо это просто не очень хорошая идея, или это так элементарно, что я не нахожу ее. Предположим, у меня есть таблица, как:Выберите SUM строк с различным условием WHERE для столбца

User | Q1 | Q2 | Q3 
ann | 3 | 2 | 5 
joe | 1 | 4 | 4 
joe | 5 | 2 | 2 
ann | 4 | 4 | 4 

То, что я хотел бы это один запрос, который возвращает сумму каждого столбца для каждого пользователя если значение для конкретного столбца больше некоторого числа. Таким образом, в приведенном выше примере, то результат будет:

User | Q1 | Q2 | Q3 
ann | 7 | 4 | 9 
joe | 5 | 4 | 4 

Если минимум за столбец 3. Но я знаю, что если я попробую

WHERE Q1 >= 3 AND Q2 >= 3 AND Q3 >= 3 

Я бы не получил значения строк в совокупности, если все 3 не совпадают с минимумом. Хотя если я использую

WHERE Q1 >= 3 OR Q2 >= 3 OR Q3 >= 3 

Я бы получил все нужные строки, но получил бы значения в совокупности ниже минимума.

Можно ли это сделать элегантно в одном запросе?

ответ

3

Так используйте IF:

SELECT 
    SUM(IF(Q1>=3, Q1, 0)) AS Sum_Q1, 
    SUM(IF(Q2>=3, Q2, 0)) AS Sum_Q2, 
    SUM(IF(Q3>=3, Q3, 0)) AS Sum_Q3, 
    user 
FROM 
    t 
GROUP BY 
    user 
+0

Будет тот же метод работы для 'AVG()', если я не хочу, значения ниже порога, чтобы быть разложены в (так AVG (5,0) = 5 не 2.5) – Anthony

+0

NVM, AVG не считает 'NULL', поэтому я могу заменить NULL на 0 из вашего примера. Потрясающие. – Anthony

+0

Нет, это не сработает: для 'SUM' вы добавляете ноль, но вы по-прежнему являетесь строкой _handling_ со значением меньше 3. Это означает, что если мы говорим о' AVG', это займет все строки (так если мы имеем значения 3 и 5 - это будет делать: '(3 + 0)/2'). Но это легко решить »с помощью: SUM (IF (Q1> = 3, Q1, 0))/COUNT (IF (Q1> = 3, Q1, 0))'. Или вы можете использовать 'NULL' для пропуска строк, да (я имею в виду, вы не можете использовать' 0' для 'AVG') –

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