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

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: подсчет фирм в категориях

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


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

> Без описания
dimka888
Отправлено: 14 Декабря, 2011 - 21:13:25
Post Id


Новичок


Покинул форум
Сообщений всего: 33
Дата рег-ции: Окт. 2010  


Помог: 0 раз(а)




Здравствуйте, необходимо подсчитать количество фирм в категориях. Одна фирма может быть в нескольких категориях. ID категорий перечислены в поле cat_id в таблице фирм.

SELECT cat.cid, (SELECT COUNT(*) FROM dle_hte_firms as f WHERE f.cat_id REGEXP '[[:<:]]('+cat.cid+')[[:>:]]' AND f.approve = 1) as count FROM dle_hte_firms_category as cat

необходимо примерно таким запросом подсчитать количество... Но вот проблема, как передать cat.cid в регулярное выражение? Если делать как у меня, то не верно считает, если подставить цифру, то верно. Вообще цифры получается на много больше чем на самом деле.
 
 Top
Panoptik
Отправлено: 14 Декабря, 2011 - 22:32:38
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2493
Дата рег-ции: Нояб. 2011  
Откуда: Одесса, Украина


Помог: 131 раз(а)




CODE (SQL):
скопировать код в буфер обмена
  1.  
  2. SELECT `c`.`cid`, COUNT(`c`.`cid`) FROM `dle_hte_firms_category` AS `c` LEFT JOIN `dle_hte_firms` AS `f` ON `c`.`cid` = `f`.`cat_id` GROUP BY `c`.`cid`

(Отредактировано автором: 14 Декабря, 2011 - 22:35:43)



-----
Just do it
 
 Top
dimka888
Отправлено: 14 Декабря, 2011 - 22:46:32
Post Id


Новичок


Покинул форум
Сообщений всего: 33
Дата рег-ции: Окт. 2010  


Помог: 0 раз(а)




Дело в том, что в поле cat_id содержится перечисление категорий через запятую, поэтому такое условие не подходит
CODE (htmlphp):
скопировать код в буфер обмена
  1. `c`.`cid` = `f`.`cat_id`


CODE (htmlphp):
скопировать код в буфер обмена
  1.  
  2. CREATE TABLE IF NOT EXISTS `dle_hte_firms` (
  3. `id` int(11) NOT NULL AUTO_INCREMENT,
  4. `cat_id` varchar(150) NOT NULL,
  5. `name` varchar(100) NOT NULL,
  6. PRIMARY KEY (`id`)
  7. ) ENGINE=MyISAM DEFAULT CHARSET=cp1251 AUTO_INCREMENT=8 ;
  8.  
  9. INSERT INTO `dle_hte_firms` (`id`, `cat_id`, `name`) VALUES
  10. (1, '1,3,14,63', 'Фирма 1'),
  11. (2, '10,2,13,63', 'Фирма 2'),
  12. (3, '1,3,14,63', 'Фирма 3'),
  13. (4, '54,119,72,24,34,42', 'Фирма 4'),
  14. (5, '1,3,14,63', 'Фирма 5'),
  15. (6, '1,3,14,63', 'Фирма 6'),
  16. (7, '99,100,101,103,108,114,118,450,340,341,355,337,119', 'Фирма 7');
  17.  
  18. CREATE TABLE IF NOT EXISTS `dle_hte_firms_category` (
  19. `cid` mediumint(5) NOT NULL AUTO_INCREMENT,
  20. `cat_name` varchar(100) NOT NULL DEFAULT '',
  21. `count` mediumint(5) NOT NULL DEFAULT '0',
  22. PRIMARY KEY (`cid`)
  23. ) ENGINE=MyISAM DEFAULT CHARSET=cp1251 AUTO_INCREMENT=3 ;
  24.  
  25. INSERT INTO `dle_hte_firms_category` (`cid`, `cat_name`, `count`) VALUES
  26. (1, 'Крыши', 0),
  27. (2, 'Двери', 0);
  28.  
  29.  


Выполнив:
CODE (htmlphp):
скопировать код в буфер обмена
  1. SELECT cat.cid, (SELECT COUNT(*) FROM dle_hte_firms as f WHERE f.cat_id REGEXP '[[:<:]]('+cat.cid+')[[:>:]]') as count FROM dle_hte_firms_category as cat


получаем (неверное):
1 7
2 2

Выполняя по отдельности:
CODE (htmlphp):
скопировать код в буфер обмена
  1. SELECT COUNT(*) FROM dle_hte_firms as f WHERE f.cat_id REGEXP '[[:<:]](1)[[:>:]]'

получаем верное 4

CODE (htmlphp):
скопировать код в буфер обмена
  1. SELECT COUNT(*) FROM dle_hte_firms as f WHERE f.cat_id REGEXP '[[:<:]](2)[[:>:]]'

получаем верное 1
 
 Top
Panoptik
Отправлено: 14 Декабря, 2011 - 22:56:59
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2493
Дата рег-ции: Нояб. 2011  
Откуда: Одесса, Украина


Помог: 131 раз(а)




ваше соотношение между таблицами называется многие ко многим. я в таких случаях предпочитаю пользоваться дополнительной таблицей в которой хранятся отношения между таблицами например из вашего примера содержимое будет примерно такое
id cat_id firm_id
... 1 1
... 1 3
... 1 14
... 1 63
... 2 10
... 2 2
... 2 13
... 2 63
... 3 1
... 3 3
... 3 14
... 3 63

и т. д. работая с промежуточной таблицей находить требуемые значения гораздо проще, хотя наверное это кому как. а ваш изврат с регуляркой в sql наверное прийдется изначально обрабатывать в пхп, хотя если наверняка знать что цифры в ряду "'1,3,14,63'" с двух сторон отделяются запятыми, то вам хватит обыкновенного LIKE '%,3,%'

CODE (SQL):
скопировать код в буфер обмена
  1. SELECT cat.cid, (SELECT COUNT(*) FROM dle_hte_firms AS f WHERE f.cat_id LIKE '%,cat.cid,%' AND f.approve = 1) AS count FROM dle_hte_firms_category AS cat
както так, но получается мутновато


-----
Just do it
 
 Top
dimka888
Отправлено: 14 Декабря, 2011 - 23:27:36
Post Id


Новичок


Покинул форум
Сообщений всего: 33
Дата рег-ции: Окт. 2010  


Помог: 0 раз(а)




Увы, но ради подсчета переделывать структуру бд слишком накладно... Легче пхп подключить в подсчет.

А для того чтобы узнать где стоит категория в начале, середине или конце придется запрос делать лишний...

хотя можон попробовать так:
CODE (htmlphp):
скопировать код в буфер обмена
  1.  
  2. f.cat_id LIKE '%,cat.cid,%' OR f.cat_id LIKE '%cat.cid,%' OR f.cat_id LIKE '%,cat.cid%'
  3.  


Хотя в этом варианте могут быть лишние вхождения по краям... Буду пробовать регулярку писать, если не получится то тогда уже пхп
 
 Top
tuareg
Отправлено: 15 Декабря, 2011 - 08:35:14
Post Id


Участник


Покинул форум
Сообщений всего: 1234
Дата рег-ции: Июнь 2010  


Помог: 69 раз(а)




dimka888 пишет:

CODE (htmlphp):
скопировать код в буфер обмена
  1.  
  2. f.cat_id LIKE '%,cat.cid,%' OR f.cat_id LIKE '%cat.cid,%' OR f.cat_id LIKE '%,cat.cid%'
  3.  


Этот вариант не учитывает ситуацию когда одно значение типа
(1, '1', 'Фирма 1')
Т.е вариант c LIKE ни как Вам не подходит.
В данной ситуации, я думаю оптимальней все-таки переделать БД, если нет то дергать всю таблицу, и уже PHP считать.
Но это ооочень не оптимально.
 
 Top
dimka888
Отправлено: 15 Декабря, 2011 - 16:46:47
Post Id


Новичок


Покинул форум
Сообщений всего: 33
Дата рег-ции: Окт. 2010  


Помог: 0 раз(а)




Подсказали решение
CODE (SQL):
скопировать код в буфер обмена
  1.  
  2. SELECT cat.`cid`, cat.`cat_name`, count(cat.`cid`) `count`
  3. FROM `dle_hte_firms_category` cat, `dle_hte_firms` f
  4. WHERE concat(',', f.`cat_id`, ',') LIKE concat('%,', cat.`cid`, ',%')
  5. GROUP BY cat.`cid`, cat.`cat_name`;
  6.  
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« SQL и Архитектура БД »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB