Javascript-форум (https://javascript.ru/forum/)
-   Серверные языки и технологии (https://javascript.ru/forum/server/)
-   -   SQL, проблема с группировкой (https://javascript.ru/forum/server/51843-sql-problema-s-gruppirovkojj.html)

iNfantry 21.11.2014 14:42

SQL, проблема с группировкой
 
Подскажите пож, уже много часов бьюсь над проблемой, возможно чего-то не понимаю.

Есть таблицы

cat(id, title) - к примеру таблица одноуровневых категорий
cat_stat(cat_id, num, date) - статистика категории с каким-то абстрактным счетчиком, меняющимся со временем, примари кей на cat_id и date)
item(id, title) - какие-то данные, связанные с категориями, впринципе на эту таблицу вообще пофиг, просто для наглядности
cat_item(cat_id, item_id) - таблица связей предыдущей таблицы с категориями

Итак, в таблице cat_stat пишется какая-то инфа несколько раз в сутки для каждой категории, для того чтобы отслеживать изменение счетчика по времени, все обычно. Есть задача - получить список категорий с количеством item_id в таблице связей и суммой счетчиков из таблицы статистики (хотя пофигу на самом деле на сумму, можно и просто count(*) из той таблицы). Вобщем две групповые функции для двух таблиц которые джойнятся к первой. Казалось бы всё просто, НО - количество записей из таблицы cat_item умножается на количество записей в таблице статистики! Спрашивается почему и как это исправить?
Запрос:

SELECT c.id, COUNT(ci.item_id), SUM(cs.num)
FROM cat c, cat_item ci, cat_stat cs
WHERE c.id=ci.cat_id AND c.id=cs.cat_id
GROUP BY c.id

Еще раз - значение COUNT(ct.item_id) умножается на количество записей в cat_stat! Тоесть если в cat_item 3 записи для какой-то категории, а в cat_stat - 4 записи, то COUNT(ct.item_id) = 3*4 = 12, значение SUM(cs.num) также складывается 12 раз! Поясните, если я что-то в группировке не понимаю.

ksa 21.11.2014 14:53

Цитата:

Сообщение от iNfantry
получить список категорий с количеством item_id в таблице связей и суммой счетчиков из таблицы статистики

Как вариант...

Select
   a.id,
   a.title,
   (Select
       count(*)
    From
       cat_item as b
    Where
       b.cat_id=a.id
   ) as cntItem,
   (Select
       sum(c.num)
    From
       cat_stat as c
    Where
       c.cat_id=a.id
   ) as sumNum
From
   cat as a

ksa 21.11.2014 14:56

Цитата:

Сообщение от iNfantry
Казалось бы всё просто, НО - количество записей из таблицы cat_item умножается на количество записей в таблице статистики! Спрашивается почему и как это исправить?

Потому как у тебя не такое, как тебе нужно, количество записей в твоем декартовом кубе... Убери GROUP BY и агрегатные функции count(), sum() - увидишь тот суп, который ты поимел...

Ну, а исправление я уже показал...

iNfantry 21.11.2014 15:03

Вот-вот, правильно понял проблему с декартовым кубом! Получается что так сделать нельзя? Чтобы группировка сработала для двух таблиц для разного количества записей для каждой из них соответственно? С ползапросами всё конешно понятно, только не слишком ли это накладно для такой простой задачи?

iNfantry 21.11.2014 15:29

Всё, разобрался сам! Надо в каждый агрегат ДИСТИНКТ вставить и всё как надо работает!

ksa 21.11.2014 15:33

Цитата:

Сообщение от iNfantry
только не слишком ли это накладно для такой простой задачи?

На то всегда много дебатов... :D

ksa 21.11.2014 15:36

iNfantry, как вариант можно взять табличку с самым большим количеством записей... Сгруппировать по полю cat_id... А вторую "подключить" вложеным селектом...

Но так есть риск, что не все ИД из таблицы cat будут отображены в результате... :(


Часовой пояс GMT +3, время: 20:36.