Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум (новые сообщения вниз) Структурный форум

тема: сложный запрос

Сообщения:  [1-5] 

 
 автор: kosta_in_net   (13.04.2010 в 00:53)   письмо автору
 
   для: Trianon   (12.04.2010 в 23:43)
 

к сожалению, "кроме ключа" нужно. Про конструктор запроса я не спрашивал, так написать его не сложно. Главное знать, какой запрос он должен формировать. EXPLAIN и BENCHMARK должны применяться на реальных данных, коих должно быть достаточно много и кои должны быть различны. На 10 наскоро набитых записях общие выводы не сделаешь. Поэтому, тут больше обращение к вашему практическому опыту. Я изложил свои аргументы. Возможно 10 мелких выборок будут происходить дольше, чем одна крупная. Но при БОЛЬШОЙ базе и большем количестве условий (ни 2, ни 10, а, к примеру, 50), такая выборка сожрет много ресурсов. Если это еще и часто будет происходить... думаю, тормоза серверу обеспечены.
Это мое мнение. Оно основано не на конкретном опыте и не на теории, относящейся к конкретному случаю. Оно основано на общих наблюдениях: если сгребать все бульдозером, получится громоздким, медленным и ресурсоемким.

Кстати, для "или", сравнивающего одно и то же поле, лучше FIND_IN_SET(vid,"1,2,3"), чем vid=1 OR vid=2 OR vid=3. Да и конструктор такой сделать легче (просто превратить массив в строку, разделенную запятыми: implode(",", $_GET['vid']) - и вся кнструкция). Но поскольку изначально задача стояла именно в коструировании для "и", FIND_IN_SET для примера не сразу пришло в голову. Просто думал о том, что vid=1 AND vid=2 AND vid=3, в отличие от vid=1 OR vid=2 OR vid=3 не будет работать. Поэтому соорудил конструктор для vid=1 OR vid=2 OR vid=3, чтобы показать, что это не фиксированный запрос, а запрос, который набирается в зависимости от условий.

  Ответить  
 
 автор: Trianon   (12.04.2010 в 23:43)   письмо автору
 
   для: kosta_in_net   (12.04.2010 в 23:06)
 

в принципе, если ничего кроме ключа не нужно, можете попробовать и без основной.
SELECT DISTINCT  l1.id 
  FROM  link l1 
    JOIN link l2 ON m.id = l2.id AND l2.vid = 'другое значение'  
WHERE l1.vid = 'одно значение' 


На счет того, какой быстрее - так есть EXPLAIN и BENCHMARK
Я загадывать не буду. Тем более что задачу решал при явной неполноте условия.

Относительно конструирования запроса по данным из формы - тут уж извините, коней на переправе не меняют.
Если Вы хотели выяснять этот момент, то так бы проблему и описывали.

  Ответить  
 
 автор: kosta_in_net   (12.04.2010 в 23:06)   письмо автору
 
   для: Trianon   (12.04.2010 в 21:53)
 

я предполагал такой вариант. Есть только 1 проблема: вариантов типа 'одно значение' может быть с пол сотни, а может не быть ни одного... К примеру, поиск людей, живущих в Москве, имеющих высшее образование и работающих по строительной специальности (3 условия должны совпасть одновременно)... но если ограничения в форме поиска не поставлены, то значит не делать джонов... В то же время, ограничений может быть и пол сотни. С условием OR все просто:
        if(@$_GET['vid']){
            foreach($_GET['vid'] AS $value){
                if(@$linkwhere){
                    $linkwhere.=' OR ';
                }
                @$linkwhere.='vid='.$value;
            }
            if(@$where){
                $where.=' AND ('.$linkwhere.')';
            }else{
                $where=$linkwhere;
            }
        }
где:
$_GET['vid'] - вероятный массив ограничений.
$where - другие параметры выборки (как раз для main-таблицы)
И таблица джоница к основной

Сейчас соорудил такой конструктор запроса:

        if(@$_GET['vid']){
            foreach($_GET['vid'] AS $value){
                if(@$subsql){
                    $subsql=' SELECT id FROM '.link.' WHERE vid='.$value.' AND id IN ('.$subsql.')';
                }else{
                    $subsql=' SELECT id FROM '.link.' WHERE vid='.$value;
                }
            }
            if(@$where){
                $where.=' AND id IN ('.$subsql.')';
            }else{
                $where=' id IN ('.$subsql.')';
            }
        }

Джонить таблицы не приходится.
Вроде работает (неуверенность вызывается недостатком опыта). Хотелось бы узнать мнение столь опытного человека, как Трианон. Какой вариант оптимальней? Ваш, или мой? Ваш сконструировать легче. Но, насколько я понимаю, для вашего создается здоровенный массив данных, обединяющий основную таблицу и множество копий вспомогательной. А в моем варианте происходит несколько небольших последовательных выборок, каждая из которых уточняет предыдущую, никакого гигантсгого массива не формируется, так как ничего не джонится. Я правильно понимаю ситуацию? Какой метод в итоге лучший?

  Ответить  
 
 автор: Trianon   (12.04.2010 в 21:53)   письмо автору
 
   для: kosta_in_net   (12.04.2010 в 21:48)
 

для начала нужно опереться на ту таблицу, которая поставляет первичный ключ к чужому link.id

SELECT m.id 
  FROM  main m 
    JOIN link l1 ON m.id = l1.id AND l1.vid = 'одно значение' 
    JOIN link l2 ON m.id = l2.id AND l2.vid = 'другое значение' 

  Ответить  
 
 автор: kosta_in_net   (12.04.2010 в 21:48)   письмо автору
 
 

Таблица со структурой:
CREATE TABLE IF NOT EXISTS `link` (
`id` int(11) unsigned NOT NULL,
`vid` smallint(6) unsigned NOT NULL DEFAULT '0',
KEY `vid` (`vid`),
KEY `id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;
id - это НЕ уникальный идентификатор записи. Это идентификатор записи в другой таблице, по которому они связываются, но это сейчас не имеет значения. В таблице может быть много записей с одинаковым id, но разным vid. Нужно выбрать такие id, в токорых vid имеет значение и 'одно значение', и 'другое значение'.
Как это сделать?

  Ответить  

Сообщения:  [1-5] 

Форум разработан IT-студией SoftTime
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования