Текущий архив: 2004.11.28;
Скачать: CL | DM;
ВнизПомогите пожалуйста с SQL запросом Найти похожие ветки
← →
Undert © (2004-11-07 20:06) [0]Есть некие таблицы
"tasks (id, name)", "tasks_access (taskid, userid)", "tasks_sub (id, name)", "tasks_sub_access (subtask, userid)", "users (id, name)".
Таблица tasks содержит некие элементы, доступ для пользователей (users) к которым определяется через таблицу tasks_access, есть подэлементы (tasks_sub), доступ к которым определяется через таблицу tasks_sub_access.
Как зная id элемента (task) и id подэлемента (subtask) получить результат со всеми пользователями, которые имею доступ к данному подэлементу, данного элемента ?
Дошел до такого запроса
SELECT users.* FROM users, tasks_sub_access, tasks_access WHERE ((tasks_access.tree_id="1") AND (tasks_access.user_id=users.id) AND (tasks_sub_access.subtree_id="1") AND (tasks_sub_access.user_id=users.id))
Самому понятно что не правильно, больше не получается придумать, помогите :)
Спасибо!
← →
Undert © (2004-11-07 20:07) [1]Вернее (описался с tree)
SELECT users.* FROM users, tasks_sub_access, tasks_access WHERE (users.user_access=1) OR ((tasks_access.task_id="1") AND (tasks_access.user_id=users.id) AND (tasks_sub_access.subtask_id="1") AND (tasks_sub_access.user_id=users.id))
← →
Undert © (2004-11-07 20:14) [2]P.S. Забыл: еще есть скрепляющая таблица tasks_subtasks (taskid, subtaskid) - какие подэлементы есть у элемента
← →
Cobalt © (2004-11-08 00:58) [3]Попробуй сначала написать простым человеческим языком:
Выбрать все записи о правах пользователей, где :
<>
Кстати, ты не упомянул такую вещь: доступ к подэлементам наследуется от элементов("родителей")?
← →
Undert © (2004-11-08 02:19) [4]Cobalt ©, нет, наследство не нужно, это в запросе никак не должно обрабатыватся...
Хочется следующего:
Выбрать все записи (USERS) о тех пользователях, которые имеют доступ (TASKS_SUB_ACCESS) к данному подпункту (TASKS_SUB) данного пункта (TASKS), при условии если данный подпункт присутствует в данном пункте (TASKS_SUBTASKS) и пользователь имеет доступ к данному пункту (ACCESS)
Логически, разбито на несколько запросов:
ДАНО TASK_ID, SUBTASK_IDR = MYSQL_QUERY("SELECT * FROM USERS")
WHILE (ROW = MYSQL_FETCH_ARRAY(R)) {
RR = MYSQL_QUERY("SELECT * FROM ACCESS WHERE USER_ID=ROW[ID] AND TASK_ID=TASK_ID");
IF (MYSQL_NUMROWS(RR)<1) CONTINUE; //Нет доступа к TASK
RR = MYSQL_QUERY("SELECT * FROM tasks_sub_access WHERE USER_ID=ROW[ID] AND SUBTASK_ID=TASK_ID");
IF (MYSQL_NUMROWS(RR)<1) CONTINUE; //Нет доступа к SUBTASK
RR = MYSQL_QUERY("SELECT * FROM tasks_subtasks WHERE TASK_ID=TASK_ID AND SUBTASK_ID=SUBTASK_ID");
IF (MYSQL_NUMROWS(RR)<1) CONTINUE; //Нет такого SUBTASK в данном TASK
// ВСЕ ОСТАЛЬНЫЕ ПРОШЛИ ПРОВЕРКУ
}
← →
Undert © (2004-11-08 02:20) [5]ЗЫ: Кол-во запросов в моем варианте просто ужасающе :))
← →
Johnmen © (2004-11-08 02:22) [6]>Undert © (08.11.04 02:19) [4]
"Ты не умничай, ты рукой покажи." (с) известный анекдот
← →
Undert © (2004-11-08 02:29) [7]Johnmen ©
?
← →
Johnmen © (2004-11-08 02:33) [8]>Undert © (08.11.04 02:29) [7]
!
Сформулируй попроще. Если, конечно ещё интересен ответ...
← →
Undert © (2004-11-08 14:33) [9]>> Сформулируй попроще. Если, конечно ещё интересен ответ...
Гмм... :) А как тут проще то можно ?
Попробую иначе:
Есть некая древовидная двухуровневая структура:
- Объект1
----- Подобъект1
----- Подобъект2
----- ПодобъектN
- ОбъектM
----- Подобъект1
----- Подобъект2
----- ПодобъектN
Количество подобъектов ограничено их возможным списком (таблица SUBTASKS {ID, NAME}).
Определение списка подобъектов происходит через связующий список (TASKS_SUBTASKS {ID, TASK_ID, SUBTASK_ID}), где присутствие строки TASK_ID-SUBTASK_ID означяет присутсвие данного подобъекта в данном объекте.
К такой структуре в различном виде имеют доступ пользователи (USERS {ID, NAME}). Доступ к первому уровню объектов определяется через список (ACCESS {ID, USER_ID, TASK_ID}), где присутствие строки TASK_ID-USER_ID означает, что ользователь имеет доступ к данному объекту.
По такому же способу пользователю назначается доступ и к объектам второго уровня, через лист SUB_ACCESS {ID, USER_ID, SUBTASK_ID}).
Для запроса дано: TASK_ID (идентификатор объекта первого уровня), USER_ID (идентификатор пользователя), SUBTASK_ID (идентификатор второго уровня)
Необходимо одним запросом выбрать всех пользователей (USERS), которые имеют доступ к данному объекту второго уровня (SUB_ACCESS), учитывая то, что пользователь имеет доступ к объекту первого уровня (ACCESS), а так же, что объект второго уровня присутствует в объекте первого уровня (TASKS_SUBTASKS).
← →
Undert © (2004-11-08 14:35) [10]Извиняюсь, пропустил столбец
По такому же способу пользователю назначается доступ и к объектам второго уровня, через лист SUB_ACCESS {ID, USER_ID, TASK_ID, SUBTASK_ID}).
← →
Deep © (2004-11-08 15:08) [11]
> Undert © (07.11.04 20:14) [2]
> P.S. Забыл: еще есть скрепляющая таблица tasks_subtasks
> (taskid, subtaskid) - какие подэлементы есть у элемента
"tasks (id, name)"
"tasks_sub (id, name)"
"tasks_subtasks (taskid, subtaskid)"
>>>>>>>>>> это есть обычное дерево
"tasks (id, parentid, name)"
Кстати, тогда и "tasks_access (taskid, userid)" и "tasks_sub_access (subtask, userid)" станут одной таблицей.
Советую почитать статьи о НОРМАЛИЗАЦИИ таблиц.
Сначала правильно спроэктируй таблицы, а уже потом пиши к ним запросы.
← →
Cobalt © (2004-11-08 20:18) [12]> Deep © (08.11.04 15:08) [11]
Точно-точно
← →
Undert © (2004-11-08 21:14) [13]Deep © ::))
Не понял ты совсем :))) Если б это было б деревом я б это написал как надо, задача намного сложнее, здесь вылил некую ее часть. TASKS - да дереве, даже nested если будет интересно (к вопросу о НОРМАЛИЗАЦИ таблиц c parent_id), SUBTASKS - к дереву отношение не имеет никакое, это разделы ветки дерева. Описал я это иммено так, что бы легче было понять задачу.
← →
Cobalt © (2004-11-08 22:10) [14]2 Undert © (08.11.04 21:14) [13]
Нууу, так не интересно - ты скрываешь интересные части!
Объясни полностью - что к чему, а то играешь в прятки. :(
← →
Undert © (2004-11-08 22:21) [15]Cobalt ©
Да что вы за люди :))) Яж объяснил проще некуда, потом вдруг какие то мысли с деревьями ... эхххх :)))) вы что хотите что бы я таблицу расписал со всей сотней столбцов и что к чему, совершенное не нужно в требующемся запросе ? :)))))
Я просто попросил помощи в составлении запроса, а вы издеваетесь :(
← →
Cobalt © (2004-11-08 22:27) [16]Видишь ли - если
> доступ к подэлементам не наследуется от элементов("родителей")
То id элемента (task) не требуется.
Но, судя по тому, что ты всё-таки пихаешь сюда эти task, то они, наверное, зачем-то нужны...
Я потому и говорю - раскрывай карты.
← →
Undert © (2004-11-08 22:41) [17]Cobalt ©
Ты немного не понял, попытаюсь объяснить с раскрытими картами:
Есть дерево, большое дерево в таблице TASKS, доступ к какждой ветки данного дерева для данного пользователя определяется таблицей ACCESS.
- в полне классическая ситуация с деревом
У каждой ветки дерева, помимо "детей", есть разделы SUBTASKS, количество и тип которых для данной ветки дерева определяется таблицей TASK_SUBTASKS. Список таких разделов - динамический. Т.е. необходим ID раздела.
К каждому разделу ветки пользователю так же назначется доступ, но через таблицу SUB_ACCESS.
В целом - не надо искать иммется ли доступ в дереве к родителю что бы понять ессть ли доступ к данной ветки, поэтому я и сказал что наследствие не требуется, понимая под элементом - ветку дерева.
Ветка дерева и раздел - разные весщи.
← →
Undert © (2004-11-08 22:42) [18]соори за грамматику %)
← →
Undert © (2004-11-08 22:47) [19]>Список таких разделов - динамический. Т.е. необходим ID раздела.
Пояснение: одной таблицей доступа нелья ограничиться.
← →
vecna © (2004-11-09 00:14) [20]Во первых неправильная архитектура, имхо. каким образом можно понять что подзадача (subtask) принадлежит конкретной задаче (task)? Правельнее делать так:
tasks(id, name, prn), где prn - указатель на task(id). таким образом можно строить любое дерево.
соответствено, если есть users(id, name) и tasks_access (taskid, userid) задача тривиальна:
select distinct u.name
from users u, task_access a
where u.id = a.userid
and a.taskid = :ID
с твоим вариантом, все абсолютно тоже самое, только нужен union:
select distinct u.name
from users u, tasks_access a
where u.id = a.userid
and a.taskid = :TASK_ID
union
select u.name
from users u, tasks_sub_access a
where u.id = a.userid
and a.taskid = :SUBTASK_ID
ну или так:
select distinct u.name
from users u,
tasks_access a,
task_sub_access sa,
tasks_subtasks l,
where u.id = a.userid
and a.taskid = t.id
and t.id = l.taskid
and l.subtaskid = sa.subtask
and sa.userid = a.userid
and a.taskid = :TASK_ID
and sa.subtask = :SUB_TASK_ID
последний вариант плох, тем, что если у task нет subtask, но есть user с правами на этот task, то мы о нем ничего не узнаем (нет записи в tasks_subtasks)
← →
Undert © (2004-11-09 01:25) [21]vecna ©
ОГРОМНОЕ СПАСИБО !!!! ВСЕ ПОНЯЛ, ВТОРОЙ ВАРИАНТ ВСЕ ЖЕ ЛУЧШЕ !!! ЕЩЕ РАЗ СПАСИБО, РАЗОБРАЛСЯ !!! :)
Страницы: 1 вся ветка
Текущий архив: 2004.11.28;
Скачать: CL | DM;
Память: 0.5 MB
Время: 0.034 c