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

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Поиск по параметрам  (Прочитано 21273 раз)
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 » new

Я бы перефразировал: в такой схеме нужно столько 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 » 

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

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines