2012-03-14 2 views
2

Я запрашиваю четыре таблицы (которые: ресурсы, tag_list, resource_tags и голоса) и пытается получить список ресурсов с каждым элементом списка, сгруппированными тегами и суммой голосов за этот ресурс.Codeigniter: Выбор SUM строк дает результаты SUM раз GROUP_CONCAT?

Это моя текущая модель:

$this->db->select('*'); 
$this->db->select('GROUP_CONCAT(DISTINCT tag SEPARATOR " | ") AS tags, SUM(vote) AS sumvotes'); 
$this->db->from('resources'); 
$this->db->join('resource_tags', 'resources.r_id = resource_tags.resource_id', 'left'); 
$this->db->join('tag_list', 'tag_list.t_id = resource_tags.tag_id', 'left'); 
$this->db->join('votes', 'votes.resource_id = resources.r_id', 'left'); 
$this->db->where('resources.published', '1'); 
$this->db->group_by('resources.r_id'); 
$this->db->order_by('votes.vote', 'desc'); 
$query = $this->db->get(); 

Edit: Вот сырьевой генерируются SQL

SELECT *, GROUP_CONCAT(DISTINCT tag SEPARATOR " | ") AS tags, SUM(vote) AS sumvotes 
FROM (`olu_resources`) 
LEFT JOIN `olu_resource_tags` ON `olu_resources`.`r_id` = `olu_resource_tags`.`resource_id` 
LEFT JOIN `olu_tag_list` ON `olu_tag_list`.`t_id` = `olu_resource_tags`.`tag_id` 
LEFT JOIN `olu_votes` ON `olu_votes`.`resource_id` = `olu_resources`.`r_id` 
WHERE `olu_resources`.`published` = '1' 
GROUP BY `olu_resources`.`r_id` 
ORDER BY `olu_votes`.`vote` desc 

Это, кажется, делает все для расчета правильного количества голосов, за исключением того, что возвращает номер голосов умножается на количество тегов, которые имеет этот элемент. Кто-нибудь знает, почему это происходит? Или как решить эту проблему?

+0

Вы профилировали фактический запрос, чтобы увидеть необработанный SQL? Используйте '$ this-> output-> enable_profiler (TRUE)' и опубликуйте фактические результаты и ожидаемые результаты. Используйте ссылку [edit], чтобы обновить свой вопрос. –

+0

Поле 'vote' в вашей таблице ресурсов? – augustknight

+0

Эй, спасибо за ответы. Я добавил raw sql, результаты были в значительной степени тем, что я ожидал. И августнайт поле для голосования находится в таблице, называемой голосом, который привязан к таблице ресурсов идентификатором ресурса. – David

ответ

0

Почему вы не используете подзапрос для получения голосов? Активная запись в CI отлично подходит для простых запросов, но сложна (и медленна), когда у вас есть более сложные запросы, подобные вашим.

Возможно, это возможно с помощью Active Record, хотя я бы сначала проверил профайлер и посмотрел на разницу в скорости. В прошлый раз я сделал что-то вроде этого, он сделал разницу в 7 секунд. Я хотел бы попробовать что-то вроде этого:

$SQL = "SELECT *, GROUP_CONCAT(DISTINCT tag SEPARATOR ' | '), 
(SELECT SUM(vote) FROM olu_votes WHERE olu_votes.resource_id = olu_resources.r_id) AS sumvotes 
FROM (olu_resources) 
LEFT JOIN olu_resource_tags ON olu_resources.r_id = olu_resource_tags.resource_id 
LEFT JOIN olu_tag_list ON olu_tag_list.t_id = olu_resource_tags.tag_id 
LEFT JOIN olu_votes ON olu_votes.resource_id = olu_resources.r_id 
WHERE olu_resources.published = '1' 
GROUP BY olu_resources.r_id 
ORDER BY olu_votes.vote desc" 

$this->db->query($SQL); 

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

+0

Привет, бутылочка, спасибо за это, отлично работает! Я очень ценю помощь. – David

+0

Рад, что я могу помочь – bottleboot

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