Запрос к MySql
82 сообщения
#15 лет назад

Уважаемые Фрилансеры, что-то не получается составить запрос или додумать конструкцию. Прошу помочь.
Суть такая: Есть таблица users2options где записываются в столбцы users_id и options_value_id параметры пользователя, когда он регистрировался.
Например пол:
users_id - 7
options_value_id - 5 (Мужской)
У этого же пользователя есть, например, интересы
users_id - 7
options_value_id - 59 (Музыка)
Ну и для более понятного обяснения, есть пользовтель женского пола и с таким же интересом:
users_id - 8
options_value_id - 3 (Женский)
users_id - 8
options_value_id - 59 (Музыка)
И таки вот options_value_id у каждого пользователя очень много!
Вопрос:
Если человек выбирает в поиске Пол Мужской, Интересы Музыка.
Необходимо из базы выдернуть пользователя именно МУЖСКОГО пола и с таким интересом.
Я пытался сделать запрос вида:
Select user_id FROM users2options
WHERE options_value_id IN (3,59)
Он как и я думал выводит и пользователя с полом Женский, т.к у этого пользователя есть интерес с id 10.
Прошу Вас мне помочь. Изображение таблицы прилагается.
82 сообщения
#15 лет назад
Исправил пост
82 сообщения
#15 лет назад
Прошу помочь конкретно. В чем я тут запутался при IN выводит и женщину
1 сообщение
#15 лет назад
Мой тебе совет, сделай третье поле, куда ты будешь записывать пол, а из второго убери, так те будет проще делать запросы, хотя будет дублирование записей =)Или же тебе нужно будет сохранять результаты которые ты получаешь своим запросомЦитата ("artforever"):
Select user_id FROM users2optionsи к ним уже делать ещё один запрос на пол, других я выходов не вижу, ну или дождись может кто поумнее ответит =)
WHERE options_value_id IN (3,59)
400 сообщений
#15 лет назад
Таблица уродская, так таблицы проектируют только мудаки.Но работать с ней можно.
> Если человек выбирает в поиске Пол Мужской, Интересы Музыка.
SELECT u1.user_id FROM user2options AS u1
LEFT JOIN user2options AS u2 ON u2.user_id=u1.user_id AND u2.option_val_id=59
WHERE u1.option_val_id=5
Как-то так.
82 сообщения
#15 лет назад
Как бы вы создали таблицу?
400 сообщений
#15 лет назад
CREATE TABLE IF NOT EXISTS `interests` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(30) NOT NULL,
PRIMARY KEY (`id`)
) TYPE=MyISAM AUTO_INCREMENT=4 ;
INSERT INTO `interests` (`id`, `name`) VALUES
(1, 'Плавание'),
(2, 'Музыка'),
(3, 'Прыжки с шестом');
-- --------------------------------------------------------
CREATE TABLE IF NOT EXISTS `users` (
`user_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`gender` enum('male','female') NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(15) NOT NULL,
`last_name` varchar(30) NOT NULL,
`username` varchar(15) NOT NULL,
`password` varchar(15) NOT NULL,
`email` varchar(30) NOT NULL,
PRIMARY KEY (`user_id`),
UNIQUE KEY `username` (`username`,`email`)
) TYPE=MyISAM AUTO_INCREMENT=3 ;
INSERT INTO `users` (`user_id`, `gender`, `birth_date`, `first_name`, `last_name`, `username`, `password`, `email`) VALUES
(1, 'male', '1984-10-05', 'Вася', 'Букин', 'vbukin111', '', '***'),
(2, 'female', '1987-04-13', 'Ася', 'Бякина', 'byakina_87', '', '***');
-- --------------------------------------------------------
CREATE TABLE IF NOT EXISTS `users_interests_relations` (
`user_id` int(10) unsigned NOT NULL,
`interest_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`user_id`,`interest_id`)
) TYPE=MyISAM;
INSERT INTO `users_interests_relations` (`user_id`, `interest_id`) VALUES
(1, 2),
(1, 3),
(2, 1),
(2, 3);
Главная ошибка в том, что предполагается, будто у пользователя может быть несколько полов одновременно, то есть, проектировщик не понимает различия между перечислением и множеством.
82 сообщения
#15 лет назад
Спасибо пример понял
400 сообщений
#15 лет назад
Соответственно в приведенной выше структуре запрос будет выглядеть так:SELECT u.user_id FROM users AS u
LEFT JOIN users_interests_relations AS uir ON uir.user_id = u.user_id
WHERE u.gender = 'male' AND uir.interest_id =2
82 сообщения
#15 лет назад
Так это понятно а если есть огромное количество полей:Телосложение, Образование, Семейное положение, Наличие детей, Курение, Употребление алкоголя, и потом только интересы.
400 сообщений
#15 лет назад
Для всех полей, которые подразумевают только один вариант ответа, надо делать поля в таблице users.`body` enum('thin','normal','fat'

`education` enum('middle','high'

`children` tinyint(1) NOT NULL, # Дети: 1 - да, 0 - нет
`smoking` tinyint(1) NOT NULL, # Курение: 1 - да, 0 - нет
`drinking` tinyint(1) NOT NULL, # Алкоголь: 1 - да, 0 - нет
Интересы нужно выносить в отдельную таблицу потому что так их можно задать много всяких разных, и можно будет задавать произвольную кучу интересов для каждого пользователя.
82 сообщения
#15 лет назад
Фух, спасибо огромное
82 сообщения
#15 лет назад
Разобрался, все работает 
82 сообщения
#15 лет назад
Бывают такие затыки
400 сообщений
#15 лет назад
А ещё лучше использовать сеты для битовых значений, тогда будет совсем идеально:`bit_options` set('children','smoking','drinking'

Потом проверять, например, на курящего мужчину с детьми так:
...WHERE gender='male' AND bit_options LIKE '%children%smoking%';
82 сообщения
#15 лет назад
Спасибо тебе огромное, выручил очень сильно, за ссыль тем более