Помощник
|
Как написать оптимальный вариант INTERSECT для MySQL? |
pavelsc
|
Сообщение
#1
|
||
|
|
||
|
|||
pavelsc
|
Сообщение
#2
|
|
Есть еще такой вариант, но я не проверил его пока: SELECT itemId FROM item_group WHERE groupId='$group1' AND itemId IN ( SELECT itemId FROM item_group WHERE groupId=='$group2' AND itemId IN ( SELECT itemId FROM item_group WHERE groupId=='$group3' ) ) Ну кстати работает нормально. :goodpost: Но в принципе у меня селектов может быть любое количество, так что буду думать над генератором строки запроса. |
|
|
pavelsc
|
Сообщение
#3
|
|
так что буду думать над генератором строки запроса. Что интересно, получилось так вот: [PHP] if(isset($_GET['groups'])){ $groups = array_merge(array_diff($_GET['groups'], array('0'=>'')),array()); } $sql = ''; $brackets = ''; $groupMaxKey = count($groups) - 1; for($i=0;$i<=$groupMaxKey;$i++){ $sql .= "SELECT itemId FROM item_group WHERE groupId='".$groups[$i]."' "; if($i != $groupMaxKey){ $sql .= "AND itemId IN ("; $brackets .= ")"; } else { $sql .= $brackets; } } [/PHP] Самое обидно будет если сча придет крутой прогер и скажет что в мускл5.6 есть INTERSECT :) |
|
|
xdrew |
27.4.2012, 21:36;
Ответить: xdrew
Сообщение
#4
|
|
Можно так. Данные:
[IMG]http://funkyimg.com/u2/1621/695/46846627-04-2012_20-31-10.jpg[/IMG] Запрос: SELECT DISTINCT itemid FROM item_group AS ig1 WHERE ( SELECT DISTINCT COUNT( itemid ) FROM item_group AS ig2 WHERE ig2.itemid = ig1.itemid GROUP BY ig1.itemid ) =3 Результат: [IMG]http://funkyimg.com/u2/1621/715/74361927-04-2012_20-35-08.jpg[/IMG] |
|
|
Arks |
27.4.2012, 22:28;
Ответить: Arks
Сообщение
#5
|
|
|
|
|
xdrew |
27.4.2012, 23:19;
Ответить: xdrew
Сообщение
#6
|
|
На больших выборках должно тормозить (хотя мне кажется, что в этом случае таблица не настолько большая). Ради интереса проверю.
|
|
|
pavelsc
|
Сообщение
#7
|
|
xdrew, вот спасибо за пример запроса (просто я любитель, и использую sql по мере потребностей, так что узнал что-то новое), но к сожалению он тут не подойдет.
Дело в том что количество групп в которых может находится элемент может быть любым, а фильтрация может так же проходить с указанием любого числа групп. На данный момент у меня форма генерирует селекты со списками групп, в зависимости от того, к какому разделу принадлежат группы. Конечно это просто формальность, но просто для удобства. Из вопросов у меня остался один: 1. Насколько говнокодно выглядит формирование строки sql запроса, и делают ли так вообще нормальные программеры? Я так полагаю с группировкой есть риск что пробежит по всей таблице Пробегает в любом случае по всей таблице мой вариант. Ну если появится рабочий вариант запроса, можно посмотреть по числу транзакций что быстрее |
|
|
Arks |
28.4.2012, 1:22;
Ответить: Arks
Сообщение
#8
|
|
Насколько говнокодно выглядит формирование строки sql запроса, и делают ли так вообще нормальные программеры? Конечно, только лучше сделать это более читаемым использовав implode сколько-то раз. пример(отвелеченно): [PHP] $ins = array(); $fields = array('id', 'v1', 'v2'); foreach ($vals as $val) { $insdata = array(); foreach ($fields as $f) $insdata[] = $val[$f]; $ins[] = '('.implode(',',$insdata).')'; } $ins = 'INSERT INTO '.$tbl.' ('.implode(',',$fields).') VALUES .'.implode(',',$ins); [/PHP] По крайней мере лучше используйте не ".=" а array_push и implode для построения запроса/подзапросов, разобраться будет легче откуда что берется. Пробегает в любом случае по всей таблице мой вариант А я вовсе не про Ваш вариант, я про вариант с выборкой с конечным условием WHERE/HAVING для финального отсева нужных данных для двух приведенных примеров(Вашего с 2 подзапросами и xdrew с группировкой) и внутренние операции mysql-сервера. Часто в этом случае при группировке наблюдается fullscan вместо предварительного создания временной таблички, без видимых причин - как оптимизатор решит. А с фильтрацией по условию IN в подзапросах по индексу - такого нет никогда. Вот про что я, поэтому на реальные результаты и хотелось бы посмотреть. |
|
|
pavelsc
|
Сообщение
#9
|
|
По крайней мере лучше используйте не ".=" а array_push и implode для построения запроса/подзапросов, разобраться будет легче откуда что берется. В вашем случаем implode хорош тем, что нет проверки надо ли ставить запятую после последнего элемента. :) А по поводу и без такие приемы хороши в JS, т.к. в нем += намного медленнее чем push. |
|
|
Arks |
28.4.2012, 20:20;
Ответить: Arks
Сообщение
#10
|
|
т.к. в нем += намного медленнее чем push если говорить о js, то конкатенация через +(+=) медленнее только в IE который на каждую конкатенируемую строчку создает отдельный объект. В остальных монопенисуально. P.S. впрочем у самого проверить это руки не дошли, возможно я не прав. А мы используем для совсем сложных запросов не implode а самописный построитель, удобно когда join'ится порядка 16 табличек, кучи полей, кучи фильтров которые могут быть а могу и не быть. что-то типа [PHP] $this->db->select('a.*')->select('b.*, c.field')->from('tbl_1 as a'); $this->db->from('tbl_2 as b')->leftJoinEqual('tbl_3 as c', 'c.ext_id', 'a.id'); if ($filters) { $this->db->whereEqual('c.field_2',$filters['f']); $this->db->whereIn('a.field', array(1,2,3)); } $this->db->groupBy('b.field'); //debug echo $this->db->sql; $this->db->Marshal('Entity_test');// $this->db->getArray(); $this->db->getGroupArray('c.ext_id'); $this->db->getXML() и т.п. [/PHP] +к этому ORM'ка которая делает все еще более автоматическим Напишите один раз и не мучьтесь с читаемостью кода. Только не забывайте профилировать код, передавать все что нужно по ссылкам и т.п. а то абстракции на php могут жрать немерено ресурсов |
|
|
|
Похожие темы
Тема | Ответов | Автор | Просмотров | Последний ответ | |
---|---|---|---|---|---|
Rebex.io – Ваша инновационная платформа для обмена криптовалюты! | 3 | Rebex | 828 | Сегодня, 20:50 автор: Rebex |
|
Посоветуйте массажер для спины и шеи | 10 | Boymaster | 887 | Сегодня, 18:02 автор: Boymaster |
|
Как в пушсетках покупают по 100-200 тысяч кликов за день? | 2 | Boymaster | 658 | Сегодня, 17:52 автор: Boymaster |
|
Обучение Email Рассылкам + Софт Для Автоматизации (100к в сутки с сервера) | 10 | zennoboss | 4652 | Сегодня, 5:20 автор: Skyworker |
|
Как вы отдыхаете от работы за компом | 151 | adw-kupon.ru | 19835 | Вчера, 13:52 автор: Vmir |
Текстовая версия | Сейчас: 24.4.2024, 20:54 |