![]() |
|
Модераторы: skyboy |
![]()
|
|
| starmaster |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 149 Регистрация: 29.3.2004 Репутация: нет Всего: нет |
У меня такой вопрос. Есть таблица, например, такого содержания:
ID fname likes 1 Андрей Комедии|Боевики|Драмы 2 Дима Триллеры|Боевики|Эротика 3 Олег Драмы|Комедии|Триллеры 4 ... ... 5 ... ... Нужно отсортировать имена, к примеру, по Боевикам в алфавитном порядке. В поле likes, чёрточка | - разделитель между жанрами. Имена в поле fname уникальны. Можно ли как-нибудь отсортировать запросом или всё же лучше создать другую таблицу, где вписывать каждый жанр с именем в отдельную запись? |
|||
|
||||
| SelenIT |
|
|||
![]() баг форума ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3996 Регистрация: 17.10.2006 Где: Pale Blue Dot Репутация: 6 Всего: 401 |
starmaster, уточните вопрос. Нужно выбрать записи, где в значение likes входят Боевики, и отсортировать их по именам?
-------------------- Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму! |
|||
|
||||
| starmaster |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 149 Регистрация: 29.3.2004 Репутация: нет Всего: нет |
Ну типа:
Боевики -> Андрей, Дима Комедии -> Андрей, Олег То есть да, найти имена на каждый жанр и отсортировать их. |
|||
|
||||
| skyboy |
|
||||
|
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
в корне неверный подход. ибо чреват неприятностями, не давая никаких преимуществ. ни в скорости, ни в гибкости.
вот, смотри: проблема 1 связана с тем, что если текстовые идентификаторы интересов вводятся вручную, то нельзя гарантировать их корректность. например, человек может ввести "беовик". и что - сразу увидишь? если же вводить значения из списка, а после выбора вставлять соответствующую строку, то возникает проблема 2, которая связана с избыточностью данных. т.е. если для 100 человек задать интерес "мистический триллер", то объем хранимой информации для жанров составит 1900 байт текста. на голом месте. проблема 3 связана с производительностью. запросы с группировкой при такой структуре вообще нереальны(к примеру, сколько имеется имеется человек с интересом "эротика"?). запросы поиска(один из которых ты ожидаешь получить) будут использовать поиск по текстовому полю, что в жизни не составит конкуренцию поиску по числовому значению. итог: приведи БД к нормальной форме. Для этого выдели названия интересов в отдельную таблицу(idHobby - autoincrement и name - varchar), отдельно у тебя будут люди(idman -autoincrement и другие необходимые тебе поля. и отдельно таблица men_hobbies всего из двух полей: idman и idHobby. -- для твоей задачи решение в использовании функции locate
правда, в общем виде запрос не совсем корректен, так как найдет и записи с "боевик", и со значением "комедийный боевик". если надо, чтоб "боевик" нашло, а "комедийный боевик" - нет, можно использовать конструкцию
Добавлено через 52 секунды вон оно как уже перевернулось... Добавлено через 2 минуты и 29 секунд если ты сам определишь полный список интересов в коде - такое возможно, хоть и коряво будет. если надеешься, что оно само тебе сгруппирует для каждой заключенной между "|" строки, то такое без нормализации невозможно. |
||||
|
|||||
| starmaster |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 149 Регистрация: 29.3.2004 Репутация: нет Всего: нет |
На самом деле я довольно часто сталкиваюсь с такими задачами, когда для одной какой-то записи существует несколько других записей, которые потом повторяются для других записей, типа первой и надо отсортировать первые записи по одной из этих нескольких других. Всё верно, второй твой код sql полностью решает мою задачу, ты даже прочитал мои мысли (я хотел здесь добавить), что Комедия не тоже самое, что Новогодняя комедия. Но вот, я нормализовал по твоему совету таблицу, получилось к примеру:
1) Таблица интересов hobbies idhobby hobbyname 1 Комедии 2 Боевики 3 Эротика 2) Таблица имён men_names idman manname 1 Андрей 2 Дима 3 Олег 3) Таблица совместимостей men_hobbies idman idhobby 1 2 1 3 2 1 3 1 3 2 3 3 Какой теперь предложишь код для того, чтобы решить эту задачу? Я где-то совсем рядом топчусь... А раньше решал задачу (из моего варианта таблицы) примерно так:
Но ты прав, существуют намного лучше варианты, вот про них я в общем-то и хотел узнать... |
|||
|
||||
| SelenIT |
|
|||
![]() баг форума ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3996 Регистрация: 17.10.2006 Где: Pale Blue Dot Репутация: 6 Всего: 401 |
подойдет? -------------------- Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму! |
|||
|
||||
| Akina |
|
||||
|
Советчик ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 20581 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 106 Всего: 454 |
Совершенно стандартная задача построения связи типа многие-ко-многим.
Которую именно? Если выбрать, скажем, тех, кого колбасит от комедий, то
-------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
||||
|
|||||
| skyboy |
|
||||
|
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
вот ты и узнал хочу еще заметить, что нормальную форму(которая теперь уже имеется у тебя) запросто можно привести к денормальной, используя group_concat т.е. можно сделать так:
должно выдать тебе для каждого хобби список людей, предпочитающих его, через запятую с сортировкой по имени. можно так же свернуть три таблицы до выборки, с результатом, идентичным твоему первоначальному варианту. я к тому, что данные в нормальной форме можно денормализовывать. а наоборот - функций соотвествующих нет(чтоб функция получала на вход строку и разделитель, а на выходе - временную таблицу - аналог РНР функции explode) |
||||
|
|||||
| starmaster |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 149 Регистрация: 29.3.2004 Репутация: нет Всего: нет |
Спасибо заранее, но вот, чтобы совсем стало понятно по этой задаче, можно ли как-нибудь удалить одним запросом имена в таблице men_names, которые увлекаются комедиями, к примеру? Всё такая же задача, но как будет в случае с удалением?
|
|||
|
||||
| Akina |
|
||||
|
Советчик ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 20581 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 106 Всего: 454 |
-------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
||||
|
|||||
| skyboy |
|
|||
|
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
то, что внутри квадратных скобок необходимо только в случае, если отсутствуют внешние ключи/триггеры на удаление с men_hobbies на men_names. в противном случае эта часть пригодится. P.S. Описание синтаксиса DELETE можно посмотреть в online-руководстве. PPS Надеюсь, ничего не попутал. Сам такие конструкции делал пару раз в жизни(в смылсе - редко попадались запросы, когда надо удалить сущность из-за связей с другой сущностью), потому в приведенном коде могут оказаться недочеты. но дух передал правильно Добавлено через 44 секунды в любом случае, квадратные скобки просто для указания необязательной части. из кода при выполнении они в любом случае должны быть выброшены. |
|||
|
||||
| starmaster |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 149 Регистрация: 29.3.2004 Репутация: нет Всего: нет |
Ну да, просто я изощрялся и решал несколькими запросами, когда как задачу можно решить одним запросом, что будет намного быстрее. Именно с PHP всё это и использую. Короче нужно учить построение более сложных запросов skyboy, Akina, SelenIT Спасибо! Это сообщение отредактировал(а) starmaster - 21.12.2007, 00:44 |
|||
|
||||
| vi_k |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 43 Регистрация: 29.12.2007 Репутация: нет Всего: нет |
2skyboy:
Простите, что вмешиваюсь. Всё нравится, всё замечательно. Один маленький нюанс:
concat может принимать несколько аргументов. Поэтому можно заменить на:
|
||||
|
|||||
![]()
|
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | MySQL | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |