Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: групировка с подсчетом
Форумы портала PHP.SU » PHP » SQL и Архитектура БД » групировка с подсчетом

Страниц (1): [1]
 

1. DlTA - 01 Ноября, 2012 - 16:58:58 - перейти к сообщению
упрощенно имеем таблицу
id, type, count
нужно узнать для каждого id сумму count по каждому типу

типа
id =1, type=2, SUM(count) = 5
id =1, type=1, SUM(count) = 1
id =1, type=3, SUM(count) = 2
id =2, type=1, SUM(count) = 1
так можно закрутить на mysql?
2. Мелкий - 01 Ноября, 2012 - 17:27:46 - перейти к сообщению
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT id, type, sum(count) FROM tbl GROUP BY 1,2
3. EuGen - 01 Ноября, 2012 - 17:38:00 - перейти к сообщению
Записывать колонки как номера я бы не рекомендовал по причине того, что если запрос:
0. достаточно объемный
1. генерируется динамически, особенно через ORM
- получится затруднительное чтение подобных конструкций в будущем (придется постоянно держать в голове порядок следования колонок)
4. DlTA - 01 Ноября, 2012 - 18:57:58 - перейти к сообщению
немного я промахнулся с задачей

результат желательно в вот таком виде
id =1, SUM(count if(type=1)) = 5, SUM(count if(type=2)) = 10
id =2, SUM(count if(type=1)) = 2, SUM(count if(type=2)) = 1
id =3, SUM(count if(type=1)) = 6, SUM(count if(type=2)) = 21

при этом типов там может быть только 2


ну или чтоб уж до конца быть честным мне нужно выцепить id у которых есть че та там с type=1 но при этом для type=2 будет 0
5. EuGen - 01 Ноября, 2012 - 20:00:55 - перейти к сообщению
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT left_table.id, left_table.total AS sum_count_type_1, right_table.total AS sum_count_type FROM (SELECT id, SUM(count) AS total FROM table_name WHERE type=1 GROUP BY id) AS left_table LEFT JOIN (SELECT id, SUM(count) AS total FROM table_name WHERE type=2 GROUP BY id) AS right_table ON left_table.id=right_table.id

И, соответственно,
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT id FROM (SELECT left_table.id, left_table.total AS sum_count_type_1, right_table.total AS sum_count_type=2 FROM (SELECT id, SUM(count) AS total FROM table_name WHERE type=1 GROUP BY id) AS left_table LEFT JOIN (SELECT id, SUM(count) AS total FROM table_name WHERE type=2 GROUP BY id) AS right_table ON left_table.id=right_table.id) AS plain_table WHERE plain_table.sum_count_type_1>0 AND plain_table.sum_count_type_2=0

?
6. DlTA - 01 Ноября, 2012 - 20:42:29 - перейти к сообщению
тоесть без двойной выборки никак?
7. EuGen - 01 Ноября, 2012 - 20:47:56 - перейти к сообщению
Здесь все не так плохо - все же не DEPENDED SUBQUERY получится. Правда соединение явно не будет использовать индексов, так как таблицы временные.
Но, если я корректно понял условие, думаю, через SQL в любом случае в JOIN будет.
8. DlTA - 01 Ноября, 2012 - 21:21:14 - перейти к сообщению
в общем не так все плохо как я ожидал хотя о запросах на 2 разворота до этого думал как о чем то утопическом)
+

по примерам вот это ничего не дало
EuGen пишет:
AND plain_table.sum_count_type_2=0
пришлось заменить на
CODE (SQL):
скопировать код в буфер обмена
  1. AND (right_table.total IS NULL
  2. OR right_table.total=0)
как оказалось 0 и NULL разные вещи

и долго не мог понять почему тут
EuGen пишет:
right_table.total AS sum_count_type=2
ошибка)
9. EuGen - 01 Ноября, 2012 - 21:29:03 - перейти к сообщению
Потому что писалось без проверки, верно, не с рабочей машины. Исправлено.
10. DlTA - 02 Ноября, 2012 - 13:50:25 - перейти к сообщению
все же мне никак не дает покоя следующая конструкция
берем исходную таблицу
table (id, type, count)
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT `tt02`.`id`, `tt0`.`sumCount`
  2. FROM
  3.   ( SELECT *
  4.     FROM `table`
  5.     WHERE  `table`.`type` IN (0,2)
  6.   ) AS `tt02`
  7. JOIN (
  8.   SELECT `tt02`.`id`, SUM(`tt02`.`count`) AS `sumCount`
  9.   FROM `tt02`
  10.   WHERE `tt02`.`type`=0
  11.   GROUP BY `tt02`.`id`
  12. ) AS `tt0` ON `tt0`.`id` = `tt02`.`id`

то есть изначальная выборка в впихивается в таблицу `tt02`, в данном случае это упрощенная выборка, но в реале это пересечения 5-6 таблиц и т.д
а далее хотелось уже использовать эту `tt02` для получения разнообразных данных по типу того что было выше, но мускуль не позволяет так делать ( том формате запроса который привел я) говоря что в базе нет таблицы `tt02`,
тоесть
...
() as `tt02`
JOIN (выборка на основе `tt02`) ... // вот тут ругается
...

неужели в мускуле нет возможности сформировать сформировать некую таблицу которая потом будет использована во вложенных запросах?
11. EuGen - 02 Ноября, 2012 - 13:53:30 - перейти к сообщению
Почему же нет? Есть: http://dev[dot]mysql[dot]com/doc/refman/[dot][dot][dot]able-select[dot]html
Либо CREATE TEMPORARY
Или даже CREATE VIEW

Вопрос в том, нужно ли это.
12. DlTA - 02 Ноября, 2012 - 14:25:30 - перейти к сообщению
а по сравнению с двойной выборкой создание временной таблицы проигрывает в скорости или объеме используемой памяти?
13. EuGen - 02 Ноября, 2012 - 14:34:39 - перейти к сообщению
На самом деле создание временной таблицы, это из разряда вариантов "хуже некуда". В большинстве случаев. С другой стороны, через обычный SQL решение будет потреблять примерно такие же ресурсы за минусом накладных ресурсов на создание временной таблицы.

 

Powered by ExBB FM 1.0 RC1