环境: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个子查询。查看请求。我想要:答案 0 :(得分:2)
临时表或变量似乎是最简单的解决方案。将子查询的结果填充到临时表或变量中,然后在过程结束时执行两个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 :(得分:1)
您可以将子查询拉出来制作临时表,然后从临时表中执行您想要的两个查询。
答案 2 :(得分:1)
这是您可以做的最佳优化。当EXISTS 不完全评估结果集时,无法捕获和保留EXISTS子查询中的数据 - ,尤其是。当在子查询中找到SINGLE匹配时(用户为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
答案 3 :(得分:0)
以下是Ken Down^建议的实现,我认为其结果不应包含任何无关的行,考虑到您的目标。
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
答案 4 :(得分:-1)
这应该从两个表中返回结果集。
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'