Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Поиск по параметрам  (Прочитано 9015 раз)
0 Пользователей и 1 Гость смотрят эту тему.
nerik
Интересующийся

ru
Offline Offline

« : 18-07-2013 07:25 » 

Всем доброго дня.
Прошу помощи по одной задаче, которую все никак не могу решить.
В БД Mysql есть две таблицы. Одна содержит сессии, другая её параметры. Пример таблиц:

id              session
1       dd9442053nd84l2
2       df9tmdg4jsd0fj3gn
3       vm49ch3fp-vyh3ns
4       m8fj43cw2x9gm4fs


idses         param           val
1                   4               50
1                   6               30
2                   4               51
2                   2               11
2                   6               23
3                   7               0
3                   4               21
3                   6               99

Во второй таблице в столбце param содержатся id параметра, а в val его значение. Параметров у сессии может куча

Есть программа которая ищет сессию по заданным параметрам. Например, нужно найти сессии у которой параметр №4 больше 0 и параметр №6 больше 25. Найденные сессии это 1 и 3. Вот хотелось бы составить sql -запрос, который бы заставил mysql самой найти нужную сессию.
Спасибо.
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 18-07-2013 07:28 » 

Покажите запрос выбора нужного параметра по id сессии.
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 18-07-2013 07:40 » 

Немного в сторону: если не нужно централизовано добавлять, удалять или изменять параметры у группы пользователей, вычислять какие-либо статистики и вести учет значений, то вместо двух таблиц выгоднее одна: (session_id, data), где data — сериализованные данные.

Есть программа которая ищет сессию по заданным параметрам. Например, нужно найти сессии у которой параметр №4 больше 0 и параметр №6 больше 25. Найденные сессии это 1 и 3. Вот хотелось бы составить sql -запрос, который бы заставил mysql самой найти нужную сессию.

Ну да, вижу, что это не тот случай.
Свяжи таблицы по id=idses и добавь условий.
« Последнее редактирование: 18-07-2013 07:43 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.

Хз, я не очень просто не очень во всё это верю, во всякие там сатурны и прочую поебень.
HandKot
Молодой специалист

ru
Offline Offline

« Ответ #3 : 18-07-2013 08:23 » 

Ну да, вижу, что это не тот случай.
Свяжи таблицы по id=idses и добавь условий.
наверное лучше использовать IN или EXISTS, дабы не плодить записи и не использовать DISTINCT
Записан

I Have Nine Lives You Have One Only
THINK!
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 18-07-2013 08:25 » 

HandKot, зачем?

Где ты, Вася? (обращение к ТС)
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 18-07-2013 09:03 » 

Слав, затем, что по по условию на каждый id может быть 0 или 2 строки. DISTINCT тут вполне уместен и при правильной индексации будет не накладен.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.

Хз, я не очень просто не очень во всё это верю, во всякие там сатурны и прочую поебень.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #6 : 18-07-2013 09:12 » 

> нужно найти сессии у которой параметр №4 больше 0 и параметр №6 больше 25.
два соединения с таблицей  сессий

вопрос о существовании параметров пока не стоит.
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 18-07-2013 10:27 » 

Как вариант.
Два IN или EXISTS с подзапросами дадут аналогичный план.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.

Хз, я не очень просто не очень во всё это верю, во всякие там сатурны и прочую поебень.
nerik
Интересующийся

ru
Offline Offline

« Ответ #8 : 18-07-2013 10:50 » 

Покажите запрос выбора нужного параметра по id сессии.

Сейчас программа тупо выбирает все параметры из таблицы и в памяти идет поиск, а уже после достаю idses. Хотелось бы чтобы был один запрос, который уже выдает результат.

HandKot, зачем?

Где ты, Вася? (обращение к ТС)

Прошу прощения, был вне форума)

Немного в сторону: если не нужно централизовано добавлять, удалять или изменять параметры у группы пользователей, вычислять какие-либо статистики и вести учет значений, то вместо двух таблиц выгоднее одна: (session_id, data), где data — сериализованные данные.

Есть программа которая ищет сессию по заданным параметрам. Например, нужно найти сессии у которой параметр №4 больше 0 и параметр №6 больше 25. Найденные сессии это 1 и 3. Вот хотелось бы составить sql -запрос, который бы заставил mysql самой найти нужную сессию.

Ну да, вижу, что это не тот случай.
Свяжи таблицы по id=idses и добавь условий.

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

Можно ли сделать запрос, который бы выдал скажем такое из вышеприведенного условия:

id              session         param       val      param       val      param       val
1       dd9442053nd84l2           4         50         6          30       null       null
2       df9tmdg4jsd0fj3gn         4         51         2          11        6          23
3       vm49ch3fp-vyh3ns          7          0         4          21        6          99
4       m8fj43cw2x9gm4fs         null       null      null       null      null        null

чтобы после уже в запросе сделать условие скажем
and (param=4 and val>0) and (param=6 and val=25)
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #9 : 18-07-2013 11:20 » 

да join нужно делать столько, сколько и параметров

Ну и, соответственно, динамически составлять запрос.

Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #10 : 18-07-2013 12:51 » 

Я бы перефразировал: в такой схеме нужно столько JOIN, сколько есть условий выборки. Или, как вариант, один JOIN, но использовать группировку и COUNT, с проверкой соответствия COUNT числу условий.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.

Хз, я не очень просто не очень во всё это верю, во всякие там сатурны и прочую поебень.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 18-07-2013 16:22 » 

Чего-то я не догоняю, зачем тут многочисленные join? Тут надо лишь ветвистое where.
Код: (SQL)
SELECT DISTINCT sessions.id
FROM sessions JOIN params ON sessions.id = params.idses
WHERE
    (params.param = 4 AND params.val > 0)
AND (params.param = 6 AND params.val > 25)
Зачем тут exists и всё прочее?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #12 : 18-07-2013 18:14 » 

Дим, возможны разные подходы. Твой, кстати, пример — нерабочий. Не может у тебя условие сработать по AND — только по OR.

Вариант 1:
Код: (SQL)
SELECT idses
  FROM tab1
    JOIN tab2 ON idses = id
  WHERE ...условия...
  GROUP BY idses
  HAVING COUNT(*) = ...число условий...

Вариант 2:
Код: (SQL)
SELECT idses
  FROM tab1
  WHERE id IN (
    SELECT idses
    FROM tab2
    WHERE idses = id
      AND ...условия...
  )

Вариант 3:
Код: (SQL)
SELECT idses
  FROM tab1
    JOIN tab2 AS p1 ON p1.idses = id AND ...условие1...
    JOIN tab2 AS p2 ON p2.idses = id AND ...условие2...
    ...
« Последнее редактирование: 18-07-2013 18:20 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.

Хз, я не очень просто не очень во всё это верю, во всякие там сатурны и прочую поебень.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #13 : 18-07-2013 21:04 » 

Цитата: RXL
Не может у тебя условие сработать по AND — только по OR.
Да.

Тогда так:
Код: (SQL)
SELECT DISTINCT sessions.id
FROM sessions JOIN params ON sessions.id = params.idses
WHERE
    ((params.param = 4 AND params.val > 0) OR params.param = 6)
AND (params.param = 4 OR (params.param = 6 AND params.val > 25))
Всё равно не понимаю, зачем много join Улыбаюсь
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #14 : 18-07-2013 21:11 » 

А теперь перепиши для трех параметров. Потом для четырех и т.л. Полагаю сам признаешь, что это не лучший вариант.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.

Хз, я не очень просто не очень во всё это верю, во всякие там сатурны и прочую поебень.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #15 : 18-07-2013 22:04 » 

RXL, ничем не хуже массы join. Особенно если речь о динамическом запросе. Но выгода от единственного join очевидна.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
nerik
Интересующийся

ru
Offline Offline

« Ответ #16 : 22-07-2013 08:20 » 

RXL, ничем не хуже массы join. Особенно если речь о динамическом запросе. Но выгода от единственного join очевидна.

В этом есть минус) Вдруг параметров будет более 62, а ограничение в mysql до 61.

Дим, возможны разные подходы. Твой, кстати, пример — нерабочий. Не может у тебя условие сработать по AND — только по OR.

Вариант 1:
Код: (SQL)
SELECT idses
  FROM tab1
    JOIN tab2 ON idses = id
  WHERE ...условия...
  GROUP BY idses
  HAVING COUNT(*) = ...число условий...

Вариант 2:
Код: (SQL)
SELECT idses
  FROM tab1
  WHERE id IN (
    SELECT idses
    FROM tab2
    WHERE idses = id
      AND ...условия...
  )


Спасибо, интересные варианты) Буду пробовать.
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #17 : 22-07-2013 09:51 » 

Рекомендую первый вариант. Главное правильно проиндексировать вторую таблицу. Второй вариант таки нерабочий.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.

Хз, я не очень просто не очень во всё это верю, во всякие там сатурны и прочую поебень.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #18 : 22-07-2013 12:12 » 

Цитата: nerik
Вдруг параметров будет более 62, а ограничение в mysql до 61.
Так далеко не забирался. А где уверенность, что количество join не лимитировано, и что запрос вообще не сдохнет при 62 join-ах?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #19 : 22-07-2013 13:53 » new

Не рекомендую нагружать MySQL чрезмерным количеством join, т.к. вычисление плана будет очень долгим — есть такой недостаток.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.

Хз, я не очень просто не очень во всё это верю, во всякие там сатурны и прочую поебень.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines