Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / IN на основе SELECT / 18 сообщений из 18, страница 1 из 1
13.08.2014, 13:19:59
    #38719290
Himu
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IN на основе SELECT
Приветствую господа!
Вопрос может быть будет совсем для вас простой, но сам не могу решить проблему.
Есть таблица PAGES, в ней поля ID_PAGE (уникальный номер страницы), TITLE_PAGE (заголовок страницы)
Есть вторая таблица USERS в ней есть поле ACCESS_PAGES (здесь через запятую перечисляются ID страниц, которые доступны именно этому пользователю)
Таблица PAGES
-----------------------------
| id_pages | title_page |
-----------------------------
| 1 | Продукт |
-----------------------------
| 2 | Магазин |
-----------------------------
| 3 | Дар |
-----------------------------
| 4 | Постав |
-----------------------------




таблица USERS
------------------------
| id_user | access_list |
------------------------
| 1 | 1,2,4 |
------------------------



Что я хочу: получить перечень страниц для конкретного пользователя на основе доступных ему страниц такого формата
----------
| title_pages |
---------
| Продукт |
---------
| Магазин |
---------
| Постав |
---------

Составляю такой запрос:
Код: sql
1.
SELECT access_pages FROM users WHERE id_user = 1


Получаю строку: "1,2,4"
Потом формирую второй отдельный запрос на основе этой строки
Код: sql
1.
SELECT title_page FROM pages WHERE id_pages   IN (1,2,4)


тут я получаю искомый результат, НО я хочу получить все на основе одного запроса, а не двух самостоятельных, что-то вроде этого
Код: sql
1.
SELECT title_page FROM pages WHERE id_pages   IN (SELECT access_pages FROM users WHERE id_user = 1)


Но мне почему-то при таком запросе выдается только одна страница
----------
| title_pages |
---------
| Продукт |
---------
а остальные не отрабатываются, не могу понять в чем дело. Помогите пожалуйста -_-
...
Рейтинг: 0 / 0
13.08.2014, 13:53:33
    #38719351
tanglir
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IN на основе SELECT
Himuздесь через запятую перечисляются ID страниц, которые доступны именно этому пользователю 8434456 и вообще вся та тема
...
Рейтинг: 0 / 0
13.08.2014, 15:07:23
    #38719457
Himu
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IN на основе SELECT
Что-то я вообще от туда ничего не понял( единственное понятно: просто так моим запросом не выдаст в нужном формате
Тогда вопрос такой, а как правильно (или корректнее) оформить таблицы, чтобы можно было получить список доступных страниц для пользователей. Проект находится на стадии разработки и хотелось бы реализовать такой механизм максимально правильно и с наименьшим количеством отдельных обращений к серверу MySQL
...
Рейтинг: 0 / 0
13.08.2014, 19:30:18
    #38719785
tanglir
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IN на основе SELECT
Himu, стандартная схема:

pages (id,...)
users (id,...)
page2user (id_page,id_user)
...
Рейтинг: 0 / 0
14.08.2014, 07:12:15
    #38719926
Himu
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IN на основе SELECT
tanglirHimu, стандартная схема:

pages (id,...)
users (id,...)
page2user (id_page,id_user)

И получается количество записей в таблице page2user = pages * users? Это самый "правильный" вариант?
...
Рейтинг: 0 / 0
14.08.2014, 08:35:46
    #38719951
Hett
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IN на основе SELECT
плохая идея, сувать субселект в WHERE, подзапрос будет выполняться для сравнения каждой строки.
...
Рейтинг: 0 / 0
14.08.2014, 08:48:03
    #38719956
Hett
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IN на основе SELECT
...
Рейтинг: 0 / 0
14.08.2014, 09:47:30
    #38719982
Users
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IN на основе SELECT
Himu,

Код: sql
1.
2.
3.
select title_page, access_pages from users u
Join pages p on u.access_pages = u.id_pages
WHERE id_user = 1



Оно?
...
Рейтинг: 0 / 0
14.08.2014, 09:57:27
    #38719987
Himu
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IN на основе SELECT
UsersHimu,

Код: sql
1.
2.
3.
select title_page, access_pages from users u
Join pages p on u.access_pages = u.id_pages
WHERE id_user = 1



Оно?

Попробовал, выдает "title_page" только первой страницы, а во второй колонке перечень доступных страниц для пользователя.
Да и в принципе не могу понять смысла запроса =)
Как в JOIN можно сравнивать строку (поле "access_pages" ведь является строкой) и число (поле "id_pages" это просто число)
...
Рейтинг: 0 / 0
14.08.2014, 10:06:53
    #38719994
Users
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IN на основе SELECT
Himu,

Так, посмотрел внимательней. Неправильно сделали структуру базы данных. Не нужна вам там текстовая строка access_list, а нужно либо сделать так же id_page и вставлять 3 и более строки с id трех и более страниц , либо промежуточную таблицу.

Почему не нужно: большая возможность для юзера налажать при вводе - и в любом случае, хранение в этом поле id страниц.
...
Рейтинг: 0 / 0
14.08.2014, 10:08:12
    #38719996
sigmov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IN на основе SELECT
Himu,авторПопробовал, выдает "title_page" только первой страницы, а во второй колонке перечень доступных страниц для пользователя.
Да и в принципе не могу понять смысла запроса =)
Как в JOIN можно сравнивать строку (поле "access_pages" ведь является строкой) и число (поле "id_pages" это просто число)Ха, батенька, дак у вас база не нормализована, если в access_pages находится множество id'шников через ','.

Попробуйте, так:
Код: sql
1.
2.
3.
4.
5.
SELECT title_page
FROM users u
  INNER JOIN pages p 
    ON FIND_IN_SET(p.id_page, u.access_pages)
WHERE u.id_user = 1

Хотя, настоятельно рекомендую нормализовать базу.
...
Рейтинг: 0 / 0
14.08.2014, 10:08:44
    #38719997
Himu
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IN на основе SELECT
Hett http://dev.mysql.com/doc/refman/5.0/en/exists-and-not-exists-subqueries.html


попробовал сделать через Exist выдается так же одна строка, остальные строки не выбираются (
...
Рейтинг: 0 / 0
14.08.2014, 10:18:10
    #38720006
Himu
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IN на основе SELECT
sigmovХа, батенька, дак у вас база не нормализована, если в access_pages находится множество id'шников через ','.
Я с вами согласен с нормализацией. Нормализовать в данном случае - это создать отдельную таблицу AccessPages, в которой хранить записи вида: id_page - id_user? И прописать соответственно для каждого пользователя столько записей, сколько страниц ему доступно? Правильно ли это? Просто получается размер таблицы будет равен id_page * id_user (при полном доступе).

sigmovПопробуйте, так:
Код: sql
1.
2.
3.
4.
5.
SELECT title_page
FROM users u
  INNER JOIN pages p 
    ON FIND_IN_SET(p.id_page, u.access_pages)
WHERE u.id_user = 1


А вот это то что нужно! Спасибо большое за скрипт!
...
Рейтинг: 0 / 0
14.08.2014, 10:33:01
    #38720013
Users
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IN на основе SELECT
Himu,

Написал же. Либо в эту же users добавляйте поле, либо промежуточную. Промежуточная более верна. То, что размер таблицы может оказаться большим - и что? там два интовых поля. Индекс не забудьте, на любое поле, которое с чем-то джойнится - нужен индекс. Все будет летать, даже если размер таблицы супербольшой. :)
...
Рейтинг: 0 / 0
14.08.2014, 10:42:01
    #38720020
Himu
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IN на основе SELECT
Спасибо большое за советы и ответы. Тема закрыта
...
Рейтинг: 0 / 0
14.08.2014, 11:58:14
    #38720099
tanglir
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IN на основе SELECT
HimuА вот это то что нужно!только вот скорость скорее всего упадёт ниже плинтуса в случае реального использования
ну, конечно, если там не полтора пользователя :)
...
Рейтинг: 0 / 0
14.08.2014, 12:37:47
    #38720152
sigmov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IN на основе SELECT
Himu,HimuЯ с вами согласен с нормализацией. Нормализовать в данном случае - это создать отдельную таблицу AccessPages, в которой хранить записи вида: id_page - id_user? И прописать соответственно для каждого пользователя столько записей, сколько страниц ему доступно? Правильно ли это? Просто получается размер таблицы будет равен id_page * id_user (при полном доступе).
Верно. Но это лучше чем хранить id'шники в виде строки через ',' в поле типа VARCHAR(N). Лучше и по скорости доступа и по размеру(да, VARCHAR(N) жрет много места).
Через ',' можно хранить если это просто справочная информация, по которой выборка никогда не производится, тогда Да - денормализация оправдана.
...
Рейтинг: 0 / 0
14.08.2014, 13:02:56
    #38720179
tanglir
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IN на основе SELECT
sigmovтогда Да - денормализация оправдана.тогда это не денормализация :)
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / IN на основе SELECT / 18 сообщений из 18, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]