powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Where all in - где все строки есть в подзапросе
13 сообщений из 13, страница 1 из 1
Where all in - где все строки есть в подзапросе
    #39881139
Alex_BBB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день, помогите пожалуйста с запросом.

Есть:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
-- роли
DECLARE @Roles TABLE
(
  Id int, 
  Title nvarchar(10)
)

-- шаблоны назначения ролей
-- в шаблоне может быть несколько ролей
DECLARE @RoleTemplates TABLE
(
  Id int, 
  Title nvarchar(10)
)

-- Template многие_ко_многим Role
DECLARE @RoleTemplateToRole TABLE
(
	TemplateId int,
	RoleId int
)


-- таблица назначения ролей
-- Principal многие_ко_многим Role 
DECLARE @RoleAssigments TABLE
(
   PrincipalId int,
   RoleId int
)



Нужно получить шаблоны для Principal-ов.
Если у Principal есть все роли шаблона, то считаем что у Principal есть шаблон.
В идеале вот такая View нужна
Код: sql
1.
2.
PrincipalId int
TemplateId int



Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
insert into @Roles values (1, 'Role1')
insert into @Roles values (2, 'Role2')
insert into @Roles values (3, 'Role3')

insert into @RoleTemplates values (1, 'Template1')

insert into @RoleTemplateToRole values (1, 1)
insert into @RoleTemplateToRole values (1, 2)


insert into @RoleAssigments values (1, 1)
insert into @RoleAssigments values (1, 2)
insert into @RoleAssigments values (1, 3)

insert into @RoleAssigments values (2, 1)
insert into @RoleAssigments values (2, 3)


-- это не правильный запрос для примера
select 
	ass.PrincipalID,
	ass.RoleID,
	templToRole.TemplateId
from @RoleAssigments ass
join @RoleTemplateToRole templToRole ON ass.RoleID = templToRole.RoleId
...
Рейтинг: 0 / 0
Where all in - где все строки есть в подзапросе
    #39881151
Фотография court
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex_BBBЕсли у Principal есть все роли шаблона, то считаем что у Principal есть шаблон.
реляционное деление (?)
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
select 
	ass.PrincipalID,
	templToRole.TemplateId
from @RoleAssigments ass
join @RoleTemplateToRole templToRole ON ass.RoleID = templToRole.RoleId
group by
	ass.PrincipalID,
	templToRole.TemplateId
having count(distinct ass.RoleID) = (select count(*) from @RoleTemplateToRole xz where xz.TemplateId = templToRole.TemplateId)
...
Рейтинг: 0 / 0
Where all in - где все строки есть в подзапросе
    #39881178
Alex_BBB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
court, спасибо! Похоже оно самое
...
Рейтинг: 0 / 0
Where all in - где все строки есть в подзапросе
    #39881295
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
courtAlex_BBBЕсли у Principal есть все роли шаблона, то считаем что у Principal есть шаблон.
реляционное деление (?)
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
select 
	ass.PrincipalID,
	templToRole.TemplateId
from @RoleAssigments ass
join @RoleTemplateToRole templToRole ON ass.RoleID = templToRole.RoleId
group by
	ass.PrincipalID,
	templToRole.TemplateId
having count(distinct ass.RoleID) = (select count(*) from @RoleTemplateToRole xz where xz.TemplateId = templToRole.TemplateId)



Ужос. Иди выучи, наконец, exists.

ЗЫ. "есть все роли шаблона" = нет ролей, которых нет
...
Рейтинг: 0 / 0
Where all in - где все строки есть в подзапросе
    #39881344
Фотография court
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aleks222courtпропущено...

реляционное деление (?)
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
select 
	ass.PrincipalID,
	templToRole.TemplateId
from @RoleAssigments ass
join @RoleTemplateToRole templToRole ON ass.RoleID = templToRole.RoleId
group by
	ass.PrincipalID,
	templToRole.TemplateId
having count(distinct ass.RoleID) = (select count(*) from @RoleTemplateToRole xz where xz.TemplateId = templToRole.TemplateId)




Ужос. Иди выучи, наконец, exists.

ЗЫ. "есть все роли шаблона" = нет ролей, которых нетну так "изобрази"
Потом "померяемся" :)
...
Рейтинг: 0 / 0
Where all in - где все строки есть в подзапросе
    #39881347
Фотография court
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex_BBB,

так ещё можно. Может лучше будет ...
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
;with cte as 
	(select *, count(*)over(partition by TemplateId) as cntAll from @RoleTemplateToRole)
select 
	ass.PrincipalID,
	templToRole.TemplateId
from @RoleAssigments ass
join cte templToRole ON ass.RoleID = templToRole.RoleId
group by
	ass.PrincipalID,
	templToRole.TemplateId,
	templToRole.cntAll
having count(*) = templToRole.cntAll
...
Рейтинг: 0 / 0
Where all in - где все строки есть в подзапросе
    #39881353
iap
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Where all in - где все строки есть в подзапросе
    #39881363
Minamoto
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
courtaleks222пропущено...


Ужос. Иди выучи, наконец, exists.

ЗЫ. "есть все роли шаблона" = нет ролей, которых нетну так "изобрази"
Потом "померяемся" :) Не хватает таблички

Код: sql
1.
2.
DECLARE @Principals table (PrincipalId int)
INSERT INTO @Principals (PrincipalId) VALUES (1), (2)



Запрос будет такой:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
SELECT  
    * 
FROM    
    @Principals p
    INNER JOIN 
        @RoleTemplates t
            ON NOT EXISTS (
                SELECT 
                    * 
                FROM 
                    @RoleTemplateToRole tr 
                    LEFT JOIN 
                        @RoleAssigments ra 
                            ON ra.PrincipalId = p.PrincipalId 
                            AND ra.RoleId = tr.RoleId
                WHERE tr.TemplateId = t.Id
                    AND ra.RoleId IS NULL)



Померять было бы неплохо, потому что я не уверен, что это будет быстрее, но на этих данных все по 0, нужно либо на реальных данных смотреть, либо нагенерить побольше вариантов.
...
Рейтинг: 0 / 0
Where all in - где все строки есть в подзапросе
    #39881480
Фотография court
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Where all in - где все строки есть в подзапросе
    #39881491
Фотография court
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Minamotocourtпропущено...
ну так "изобрази"
Потом "померяемся" :) Не хватает таблички

Код: sql
1.
2.
DECLARE @Principals table (PrincipalId int)
INSERT INTO @Principals (PrincipalId) VALUES (1), (2)




Запрос будет такой:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
SELECT  
    * 
FROM    
    @Principals p
    INNER JOIN 
        @RoleTemplates t
            ON NOT EXISTS (
                SELECT 
                    * 
                FROM 
                    @RoleTemplateToRole tr 
                    LEFT JOIN 
                        @RoleAssigments ra 
                            ON ra.PrincipalId = p.PrincipalId 
                            AND ra.RoleId = tr.RoleId
                WHERE tr.TemplateId = t.Id
                    AND ra.RoleId IS NULL)




Померять было бы неплохо, потому что я не уверен, что это будет быстрее, но на этих данных все по 0, нужно либо на реальных данных смотреть, либо нагенерить побольше вариантов.как минимум стоимость запроса, для вашего, у меня "пишет" в 3-и раза меньше чем моего ...

пс
но, кстате, эти запросы, совершенно по разному будут "реагировать" на "пустой" шаблон
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
-- роли
DECLARE @Roles TABLE
(
  Id int, 
  Title nvarchar(10)
)

-- шаблоны назначения ролей
-- в шаблоне может быть несколько ролей
DECLARE @RoleTemplates TABLE
(
  Id int, 
  Title nvarchar(10)
)

-- Template многие_ко_многим Role
DECLARE @RoleTemplateToRole TABLE
(
	TemplateId int,
	RoleId int
)


-- таблица назначения ролей
-- Principal многие_ко_многим Role 
DECLARE @RoleAssigments TABLE
(
   PrincipalId int,
   RoleId int
)
DECLARE @Principals table (PrincipalId int)
INSERT INTO @Principals (PrincipalId) VALUES (1), (2)


insert into @Roles values (1, 'Role1')
insert into @Roles values (2, 'Role2')
insert into @Roles values (3, 'Role3')

insert into @RoleTemplates values (1, 'Template1')

--insert into @RoleTemplateToRole values (1, 1)
--insert into @RoleTemplateToRole values (1, 2)
--insert into @RoleTemplateToRole values (1, 4)


insert into @RoleAssigments values (1, 1)
insert into @RoleAssigments values (1, 2)
insert into @RoleAssigments values (1, 3)
insert into @RoleAssigments values (1, 4)

insert into @RoleAssigments values (2, 1)
insert into @RoleAssigments values (2, 2)
insert into @RoleAssigments values (2, 3)

--	***	1	
select 
	ass.PrincipalID,
	templToRole.TemplateId
from @RoleAssigments ass
join @RoleTemplateToRole templToRole ON ass.RoleID = templToRole.RoleId
group by
	ass.PrincipalID,
	templToRole.TemplateId
having count(*) = (select count(*) from @RoleTemplateToRole xz where xz.TemplateId = templToRole.TemplateId)

--	***	2	
SELECT  
    * 
FROM    
    @Principals p
    INNER JOIN 
        @RoleTemplates t
            ON NOT EXISTS (
                SELECT 
                    * 
                FROM 
                    @RoleTemplateToRole tr 
                    LEFT JOIN 
                        @RoleAssigments ra 
                            ON ra.PrincipalId = p.PrincipalId 
                            AND ra.RoleId = tr.RoleId
                WHERE tr.TemplateId = t.Id
                    AND ra.RoleId IS NULL)

...
Рейтинг: 0 / 0
Where all in - где все строки есть в подзапросе
    #39881495
Фотография court
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
courtпс
но, кстате, эти запросы, совершенно по разному будут "реагировать" на "пустой" шаблон
-- *** 1
PrincipalIDTemplateId

-- *** 2
PrincipalIdIdTitle11Template121Template1
...
Рейтинг: 0 / 0
Where all in - где все строки есть в подзапросе
    #39881516
Minamoto
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
courtно, кстате, эти запросы, совершенно по разному будут "реагировать" на "пустой" шаблон

Да, и это скорее в пользу решения с группировкой, т.к., по идее, фраза "Если у Principal есть все роли шаблона, то считаем что у Principal есть шаблон.", подразумевает, что у шаблона есть роли. Но в мой запрос тоже несложно добавить это условие - через ещё один exists, например.
...
Рейтинг: 0 / 0
Where all in - где все строки есть в подзапросе
    #39881519
iap
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
courtiapВот, мы как-то обсуждали: Как реализовать операцию реляционной алгебры "деление" на SQL?
вот тут ещё "было интересно" - запрос реляционное деление Чего мелочиться?

YouTube Video
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Where all in - где все строки есть в подзапросе
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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