ВЫБРАТЬ ВНУТРИ внутри подзапроса - PullRequest
2 голосов
/ 03 февраля 2011

Среда: SQL Server 2005

У меня есть запрос такого типа

SELECT *
FROM user
WHERE EXISTS(
  SELECT *
  FROM user_access
  WHERE user_access.user_id = user.user_id
  AND user_access.access IN ('HIGH_LEVEL','MEDIUM_LEVEL')
)
AND EXISTS(
SELECT *
FROM user_service
WHERE user_service.role ='Manager'
AND user.id_user = user_service.user_id
)
AND user.is_active ='True'

Но в результате я также хотел бы получить результат из подзапроса, поэтому я думаю очто-то вроде

DECLARE @user_access TABLE(user_id int,access nvarchar(30))
DECLARE @user_service TABLE(user_id int,service_id int,role nvarchar(10))
SELECT *  FROM user
    WHERE EXISTS(
      SELECT user_id,access INTO  [@user_access]
      FROM user_access
      WHERE user_access.user_id = user.user_id
      AND user_access.access IN ('HIGH_LEVEL','MEDIUM_LEVEL')
    )
AND EXISTS(
SELECT user_id , service_id,role INTO @user_service
FROM user_service
WHERE user_service.role ='Manager'
AND user.id_user = user_service.user_id
)
    AND user.is_active ='True'


SELECT * FROM @user_acess
select * from @user_service

Но я получаю следующую ошибку:

"Неверный синтаксис рядом с ключевым словом" INTO "."

Есть ли у васЛюбая идея, как я могу сделать это, не выполняя дважды подзапрос (я пробовал с временной таблицей, та же ошибка)?

РЕДАКТИРОВАТЬ: я извиняюсь за моего товарища, который пытался решить мою проблему, я забыл одну вещьУ меня есть 2 подзапроса.Смотрите запросы.Я хочу:

  • Всех активных пользователей, с высоким или средним доступом и которые являются менеджерами
  • Всех служб, в которых эти пользователи имеют
  • Все права доступаэти пользователи

Ответы [ 5 ]

2 голосов
/ 03 февраля 2011

Временная таблица или переменная может оказаться самым простым решением.Запишите результаты подзапроса во временную таблицу или переменную, а затем выполните два оператора select в конце вашей процедуры.

Declare @UserAccesses Table (
                            user_id ...
                            , access varchar(...)
                            )

Insert @UserAccesses( user_id, access )
Select UA.user_id, UA.access
From user_access As UA
    Join user As U
        On U.user_id = UA.user_Id
Where U.is_active = 'True'
    And UA.access In('HIGH_LEVEL', 'MEDIUM_LEVEL')

Select ...
From user
Where Exists    (
                Select 1
                From @UserAccess As UA1
                Where UA1.user_id = user.user_id
                )

Select user_id, access
From @UserAccesses

Обновите данные, учитывая расширение исходного вопроса

Решение для двух подзапросов по сути такое же, как и для одного, за исключением того, что вместо возврата двух наборов результатов вы возвращаете три.Как и раньше, вы используете временную таблицу / переменную для каждого подзапроса:

Declare @UserAccesses Table (
                            user_id int
                            , access nvarchar(30)
                            )

Declare @UserServices Table (
                            user_id int
                            , service_id int
                            , role nvarchar(10)
                            )

Insert @UserAccesses( user_id, access )
Select UA.user_id, UA.access
From user_access As UA
    Join user As U
        On U.user_id = UA.user_Id
Where U.is_active = 'True'
    And UA.access In('HIGH_LEVEL', 'MEDIUM_LEVEL')

Insert @UserServices( user_id, service_id, role )
Select user_id , service_id,role
From user_service
Where user_service.role ='Manager'
    And Exists  (
                Select 1
                From @UserAccesses As UA1
                Where UA1.user_id = user_service.user_id
                )

Select ...
From user
Where Exists    (
                Select 1
                From @UserServices As US1
                Where US1.user_id = user.user_id
                )

Select user_id, access
From @UserAccesses As UA
Where Exists    (
                    Select 1
                    From @UserServices As US1
                    Where US1.user_id = UA.user_id
                    )

Select user_id, access
From @UserServices
1 голос
/ 03 февраля 2011

Это самое лучшее, что вы можете сделать для оптимизации.Невозможно собрать и сохранить данные в подзапросах EXISTS - , особенно , когда EXISTS не не полностью оценивает набор результатов.Он замыкается, когда в подзапросе найдено ОДИНОЧНОЕ совпадение (одна access для пользователя), поэтому вы все равно не можете получить все записи access.

declare @user table (user_id int)
insert @user
SELECT [user].user_id
FROM [user]
WHERE EXISTS(
    SELECT *
    FROM user_access
    WHERE user_access.user_id = [user].user_id
    AND user_access.access IN ('HIGH_LEVEL','MEDIUM_LEVEL')
    )
AND EXISTS(
    SELECT *
    FROM user_service
    WHERE user_service.role ='Manager'
    AND [user].id_user = user_service.user_id
    )
AND [user].is_active ='True'

SELECT [user].* FROM [user] inner join @user u on u.USER_ID = [user].user_id
SELECT a.user_id, a.access FROM user_access a inner join @user u on u.USER_ID = a.user_id
SELECT s.user_id, s.service_id, s.role FROM user_service s inner join @user u on u.USER_ID = s.user_id
1 голос
/ 03 февраля 2011

Вы можете извлечь подзапрос, чтобы создать временную таблицу, а затем выполнить два запроса из временной таблицы.

0 голосов
/ 04 февраля 2011

Вот реализация того, что Кен Даун ^ предложил, и я думаю, что его результат не должен содержать никаких посторонних строк, учитывая то, что вы ищете.

DECLARE @user_access TABLE(user_id int,access nvarchar(30))
DECLARE @user_service TABLE(user_id int,service_id int,role nvarchar(10))

INSERT INTO @user_access
SELECT ua.user_id, ua.access
FROM user_access ua
  INNER JOIN [user] u ON ua.user_id = u.user_id
WHERE u.is_active ='True'
  AND ua.access IN ('HIGH_LEVEL','MEDIUM_LEVEL')

INSERT INTO @user_service
SELECT us.user_id , us.service_id, us.role
FROM user_service us
  INNER JOIN [user] u ON us.user_id = u.user_id
WHERE u.is_active ='True'
  AND us.role ='Manager'


SELECT u.*
FROM [user] u
  INNER JOIN (
    SELECT user_id FROM @user_access
    UNION
    SELECT user_id FROM @user_service
  ) uas ON uas.user_id = u.user_id
SELECT * FROM @user_acess
SELECT * FROM @user_service
0 голосов
/ 03 февраля 2011

Это должно вернуть набор результатов из обеих таблиц.

SELECT *
FROM user u, user_access a
WHERE u.user_id in (
  SELECT user_access.user_id
  FROM user_access
  WHERE user_access.user_id = u.user_id
  AND user_access.access IN ('HIGH_LEVEL','MEDIUM_LEVEL')
  AND user_access.user_id = u.user_id
)
AND a.user_id = u.user_id
AND u.is_active ='True'
...