2015-08-13 3 views
1

текущей таблицы События:выбрать и GROUP BY несколько столбцов на основе Max()

| eventId | personId | type | title | score | 
+-----------+------------+--------+---------+---------+ 
| 1   | 1   | movie | Mission | 12  | 
| 2   | 1   | movie | UNCLE | 32  | 
| 3   | 1   | show | U2  | 17  | 
| 4   | 1   | show | Leroy | 13  | 
| 5   | 2   | movie | Holmes | 19  | 
| 6   | 2   | movie | Compton | 14  | 
| 7   | 2   | show | Imagine | 22  | 
| 8   | 2   | show | Kane | 22  | 

MySQL Пример:

SELECT @personId:=personId as personId, 
(
    SELECT title FROM Events 
    WHERE rate = (SELECT MAX(score) FROM Events) 
    AND type = ‘movie’ AND [email protected] 
) as movie, 
(
    SELECT title FROM Events 
    WHERE rate = (SELECT MAX(score) FROM Events) 
    AND type = ‘movie’ AND [email protected] 
) as show, 
FROM Events 
GROUP BY personId 
ORDER BY personId; 

требуемый выход:

| personId | movie | show | 
+------------+----------+---------+ 
| 1   | UNCLE | U2  | 
| 2   | Holmes | Imagine | 

Желаемый результат состоит в показать оценку MAX() для фильма и шоу на человека в таблице «События». Мой фактический вывод содержит NULLS и занимает очень много времени для загрузки. В моей таблице фактических событий содержится около 20 000 записей.

UPDATE Решение (на основе первых двух ответов для повышения производительности)

SELECT e.personId, 
(
    SELECT o.title 
    FROM Events o 
    LEFT JOIN Events b 
     ON o.personId = b.personId AND o.score < b.score 
     AND o.type = b.type 
    WHERE o.type = 'movie' AND o.personId=e.personId LIMIT 1 
) as best_movie , 
(
    SELECT o.title 
    FROM Events o 
    LEFT JOIN Events b 
     ON o.personId = b.personId AND o.score < b.score 
     AND o.type = b.type 
    WHERE o.type = 'show' AND o.personId=e.personId LIMIT 1 
) as best_show 
FROM Events e 
GROUP BY e.personId 
ORDER BY e.personId 
+0

почему шоу = 'Imagine' почему не' Kane'? – Alex

+0

Потому что его eventId выше. – user3507028

+0

eventId ниже для 'Imagine' vs' Kane' – Alex

ответ

0

Я не уверен, если это именно то, что вам нужно.

Но только моя догадка, возможно, вам не нужны несколько столбцов?

http://sqlfiddle.com/#!9/04b27/4

SELECT e.* 
FROM `events` e 
left join `events` e1 
on e.type = e1.type 
and e.score<e1.score 
WHERE e1.eventId IS NULL 
GROUP BY personId, type, score 

Update Если вам нужно максимальное количество баллов на каждого человека + типа вы можете

http://sqlfiddle.com/#!9/04b27/13

SELECT e.* 
FROM `events` e 
left join `events` e1 
on e.personId = e1.personId 
and e.type = e1.type 
and e.score<e1.score 
WHERE e1.eventId IS NULL 
GROUP BY personId, score 
+0

Это быстрый запрос, но он возвращает строку с наивысшим счетом на человека независимо от типа. – user3507028

+0

??? Зачем? Вы посетили ссылку на sqlfiddle? – Alex

+0

Да, но цель состоит в том, чтобы показать максимальный результат на человека + тип: SELECT e. * FROM 'events' e left join' events' e1 по e.type = e1.type и e.score user3507028

0

Я сделал несколько изменений в запросе.

Посмотрите:

SELECT @personId:=personId as personId, 
(
    SELECT title FROM Events 
    WHERE score = (SELECT MAX(score) FROM Events WHERE type = 'movie' 
    AND [email protected]) 
    AND type = 'movie' AND [email protected] LIMIT 1 
) as movie , 
(
    SELECT title FROM Events 
    WHERE score = (SELECT MAX(score) FROM Events WHERE type = 'show' 
    AND [email protected]) 
    AND type = 'show' AND [email protected] LIMIT 1 
) as show1 
FROM Events 
GROUP BY personId 
ORDER BY personId 
+0

Спасибо, что тянет! Хотя производительность на самом деле медленная на большом наборе данных. Но этого можно было бы ожидать. Работа над переписыванием MAX() на основе ответа Алекса. – user3507028

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