Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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_ID

R = 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.53 MB
Время: 0.045 c
4-1098077456
Submarine
2004-10-18 09:30
2004.11.28
Вопрос о программирование Com- портов


1-1100540170
jenbond
2004-11-15 20:36
2004.11.28
Help, очень нужно!


1-1100624643
TSoftman
2004-11-16 20:04
2004.11.28
Копирование файлов с визуализацией


3-1099332069
MMN
2004-11-01 21:01
2004.11.28
Инкрементирование поля


1-1100660988
Bechard
2004-11-17 06:09
2004.11.28
RTL update 2 for Delphi 6 Ent