|
|
|
| Есть таблица с полями:
`id` int,
`referer_id` int,
`status` enum('good', 'semi-good', 'bad'),
`text` varchar,
`date` int,
PRIMARY KEY `id`
Примерный запрос того, что есть:
SELECT `id`, `referer_id`, `status`, `text`, `date`, MAX(`date`) AS `max_date`, COUNT(`id`) AS `count` FROM `table` GROUP BY `referer_id` ORDER BY `date` DESC;
Вся проблема в том, что всегда по разному достается `text`, `date` для группы. А нужно, чтобы доставался тест с status = 'good', а группа учитывала status = 'good' или status = 'semi-good'.
Если применять WHERE, то группа неправильно считает. Выражение HAVING тоже не смог правильно применить.
А сделать все нужно в один запрос. | |
|
|
|
|
|
|
|
для: SportSoft
(06.06.2008 в 12:34)
| | >SELECT `id`, `referer_id`, `status`, `text`, `date`, MAX(`date`) AS `max_date`, COUNT(`id`) AS `count` FROM `table` GROUP BY `referer_id` ORDER BY `date` DESC;
>
>Вся проблема в том, что всегда по разному достается `text`, `date` для группы.
По большому счету, Вы не имеете права в SELECT-списке указывать поля отсутствующие в GROUP BY без применения агрегатных функций. Запрос в этом случае становится неопределенным.
К сожалению, сказать что-то большее не получится - Ваша задача совершенно неясна. Хотя бы потому, что никакая группа ничего не считает.
Конструкция GROUP BY field заставляет сервер перед вычислением агрегатных функций разбить всю табличную выборку на группы, по одной на каждое значение (или сочетание значений) field.
После этого, для каждой группы вычисляется по одной строке. Формально, строки эти не могут содержать никаких полей, кроме группирующих, и значений агрегатных функций. У Вас же таких полей полно - id, status, text, date
Конструкция WHERE применяется до разбиения на группы. Конструкция HAVING - после вычисления агрегатов. | |
|
|
|
|
|
|
|
для: Trianon
(06.06.2008 в 13:55)
| | Trianon, то есть вместе с группирующими полями никогда нельзя подставлять обычные? :(
Поясню подробнее:
мне нужно вначале сгруппировать по REFERER_ID и получить количество с одинаковым REFERER_ID с типом good или semi-good. И плюсом выбрать к этим группам дополнительные их уникальные параметры-свойства (date, text), которые берутся из этой же группы, только им соответствует статус = 'good' (для любой группы со статусом GOOD может быть только одна заапись).
В данном случае если я использую WHERE status = good, то уникальные свойства выбираются правильно, но для группы подсчет неверен (так как не берется + status = semigood.
Если вообще не использовать WHERE, тогда подсчет ведется правильно, а уникальные параметры раз от раза меняются. | |
|
|
|
|
|
|
|
для: SportSoft
(06.06.2008 в 14:12)
| | >Trianon, то есть вместе с группирующими полями никогда нельзя подставлять обычные? :(
Не подставлять, а выбирать.
В нормальных СУБД - нельзя.
В MySQL - можно, но безо всякой надежды получить осмысленный результат.
Потому что запрос становится неоднозначным.
>Поясню подробнее:
>мне нужно вначале сгруппировать по REFERER_ID и получить количество с одинаковым REFERER_ID с типом good или semi-good.
SELECT referer_id, COUNT(referer_id)
FROM tbl
WHERE status = 'good' OR status = 'semi-good'
GROUP BY referer_id;
|
>И плюсом выбрать к этим группам дополнительные их уникальные параметры-свойства (date, text), которые берутся из этой же группы, только им соответствует статус = 'good' (для любой группы со статусом GOOD может быть только одна заапись).
Если я правильно понял, то как-то так:
SELECT g.referer_id AS g_rid, g.cnt, t.*
FROM
(SELECT referer_id, COUNT(referer_id) AS cnt
FROM tbl
WHERE status = 'good' OR status = 'semi-good'
GROUP BY referer_id;
) AS g
LEFT JOIN tbl AS t ON g.referer_id = t.referer_id AND t.status='good'
|
| |
|
|
|
|
|
|
|
для: Trianon
(06.06.2008 в 14:26)
| | Как-то так получилось вроде. :)
Спасибо большое. :) | |
|
|
|