2013-12-24 2 views
0

I имеет следующую структуру данных в моей FOOS таблице:MySQL условно SUM с помощью GROUP BY и DISTINCT

----------------------------------------------- 
| id | bar_id | baz_id | date  | value | 
----------------------------------------------- 
| 1 | 1  | 1  | 2013-12-01 | failure | 
| 2 | 1  | 1  | 2013-12-09 | failure | 
| 3 | 2  | 1  | 2013-12-02 | success | 
| 4 | 3  | 1  | 2013-12-10 | success | 
| 5 | 3  | 1  | 2013-12-01 | failure | 
| 6 | 3  | 1  | 2013-12-08 | success | 
| 7 | 1  | 2  | 2013-12-02 | success | 
| 8 | 1  | 2  | 2013-12-08 | failure | 
| 9 | 1  | 2  | 2013-12-03 | success | 
| 10 | 2  | 2  | 2013-12-07 | failure | 
| 11 | 2  | 2  | 2013-12-08 | failure | 
| 12 | 3  | 2  | 2013-12-04 | success | 
| 13 | 3  | 3  | 2013-12-14 | failure | 
----------------------------------------------- 

Моя цель состоит, чтобы получить успех/общее количество для каждого bar_id для различных baz_ids. Например:

------------------------------ 
| bar_id | successes | total | 
------------------------------ 
| 1  | 1   | 2  | 
| 2  | 1   | 2  | 
| 3  | 2   | 3  | 
------------------------------ 

Вот запрос, который работает:

SELECT foos.bar_id, 
    successes, 
    COUNT(distinct baz_id) as total 
    FROM foos 
    LEFT JOIN 
     (SELECT bar_id, count(distinct baz_id) as successes 
      FROM foos 
      WHERE value = "success" 
      GROUP BY bar_id) as other 
     ON foos.bar_id = other.bar_id 
    GROUP BY bar_id 

Есть ли способ, чтобы получить колонку успехов, используя функцию MySQL, не делая суб-выбрать? Похоже, что для этого нужно использовать GROUP_CONCAT или один из другого Group By Functions.

Редактировать

Использование SUM(value="success") близко, но считает все успехи для отдельного baz_id вместо только подсчета одного успеха:

SELECT bar_id, 
    SUM(value="success") AS successes, 
    COUNT(distinct baz_id) as total 
    FROM foos 
    GROUP BY bar_id 

------------------------------ 
| bar_id | successes | total | 
------------------------------ 
| 1  | 2   | 2  | <- Successes should be 1 
| 2  | 1   | 2  | 
| 3  | 3   | 3  | <- Successes should be 2 
------------------------------ 
+1

Я был бы очень благодарен за отзыв о том, как я могу улучшить этот вопрос, так как он становится голосом. –

ответ

8

Вы можете использовать CASE с DISTINCT, чтобы получить такой же результат;

SELECT bar_id, 
    COUNT(DISTINCT CASE WHEN value='success' THEN baz_id ELSE NULL END) successes, 
    COUNT(DISTINCT baz_id) total 
FROM foos 
GROUP BY bar_id; 

An SQLfiddle to test with.

+0

Отлично. Это именно то, что я искал. И, как я надеялся, это избавляет от значительного количества времени (~ 40%) от запроса по сравнению с версией, которую я использовал выше. –