我在数据库中有一个简单的模块基础设置表,如下所示:
Module1
UserId | Active // other columns
*00000000-0000-0000-0000-000000000AB1* | *True*
Module2
UserId | Active // other columns
*00000000-0000-0000-0000-000000000AB1* | *False*
Module3
UserId | Active // other columns
*00000000-0000-0000-0000-000000000AB1* | *True*
我想为特定用户选择模块是否处于活动状态,输出结果如下
Module1 | Module2 | Module3
True | False | True
我使用Join
尝试了此查询:
SELECT Module1 = module1.Active, Module2 = module2.Active, Module3 = module3.Active
FROM [dbo].[Module1] AS module1 JOIN
[dbo].[Module2] AS module2 ON module1.UserId = module2.UserId JOIN
[dbo].[Module3] AS module3 ON module2.UserId = module3.UserId JOIN
WHERE module1.UserId = '00000000-0000-0000-0000-000000000AB1'
它给了我所需的确切输出。但是如果在任何表中没有该用户的匹配行,则结果集中的所有列都将为空。
如果任何表没有匹配的记录,我应该如何更新我的查询以处理该表的列的值为null或结果集中的默认值。
编辑:UserId的数据类型是uniqueidentifier,而Active是bit。
答案 0 :(得分:1)
如果您拥有(或者像我一样使用CTE)一张包含您要查找的所有ID的表格,那么您只需要从该表格中继续加入:
WITH searchfor AS
(
SELECT '00000000-0000-0000-0000-000000000AB1' as UserID
)
SELECT s.UserID,
COALESCE(m1.Active,FALSE) as Module1,
COALESCE(m2.Active,FALSE) as Module2,
COALESCE(m3.Active,FALSE) as Module3
FROM searchfor s
LEFT JOIN Module1 m1 on s.UserID = m1.Userid
LEFT JOIN Module2 m2 on s.UserID = m2.Userid
LEFT JOIN Module3 m3 on s.UserID = m3.Userid
注意,如果Active是字符串,则将其更改为COALESCE(mX.Active,'FALSE')
看到编辑,尝试COALESCE(mX.Active,(CAST 0 as BIT))
如果您希望所有用户都这样做
WITH searchfor AS
(
SELECT UserID from Module1
UNION
SELECT UserID from Module2
UNION
SELECT UserID from Module3
)
答案 1 :(得分:0)
您可以使用FULL JOIN
代替INNER JOIN
。我不太了解你的WHERE
条款,但你可以这样做:
SELECT Module1 = module1.Active, Module2 = module2.Active, Module3 = module3.Active
FROM [dbo].[Module1] AS module1
FULL JOIN [dbo].[Module2] AS module2 ON module1.UserId = module2.UserId
FULL JOIN [dbo].[Module3] AS module3 ON module2.UserId = module3.UserId
WHERE (module1.UserId = '00000000-0000-0000-0000-000000000AB1' OR module1.UserId IS NULL) OR
(module2.UserId = '00000000-0000-0000-0000-000000000AB1' OR module2.UserId IS NULL) OR
(module3.UserId = '00000000-0000-0000-0000-000000000AB1' OR module3.UserId IS NULL)
<强>更新强>
或者您可以在以下内容中使用CASE
:
SELECT Module1 = module1.Active, Module2 = module2.Active, Module3 = module3.Active
FROM [dbo].[Module1] AS module1
FULL JOIN [dbo].[Module2] AS module2 ON module1.UserId = module2.UserId
FULL JOIN [dbo].[Module3] AS module3 ON module2.UserId = module3.UserId
WHERE CASE WHEN module1.UserId IS NULL THEN module2.UserId
WHEN module2.UserId IS NULL THEN module3.UserId
END = '00000000-0000-0000-0000-000000000AB1'
答案 2 :(得分:0)
两个未经测试的人:
以Stanislovas所做的为基础......
这可能有用......
SELECT module1.Active as Module1, module2.Active as Module2, module3.Active as Module3
FROM [dbo].[Module1] AS module1
FULL OUTER JOIN [dbo].[Module2] AS module2 ON module1.UserId = module2.UserId
and (module1.UserId = '00000000-0000-0000-0000-000000000AB1' or
module2.UserId = '00000000-0000-0000-0000-000000000AB1')
FULL OUTER JOIN [dbo].[Module3] AS module3 ON module2.UserId = module3.UserId
and (module2.UserId = '00000000-0000-0000-0000-000000000AB1' OR
module3.UserId = '00000000-0000-0000-0000-000000000AB1')
GROUP BY Module1, Module2, Module3, module1.userID
虽然带有联合结果的支点似乎也可以起作用......
SELECT * FROM
(
select Active
from (
Select M1.Active, userID, 'Module1' as Module from module1 m1
UNION ALL
Select M2.Active, userID, 'Module2' from module2 m2
Union all
Select M3.Active, userID, 'Module3' from module3 m3) iQry
WHERE userID = '00000000-0000-0000-0000-000000000AB1'
pivot
(
for module in ('Module1','Module2','Module3')
) piv;
答案 3 :(得分:0)
这可以工作,但第一次加入表,即此处Module1不能为空
SELECT Module1 = t1.[ACTIVE]
, Module2 = t2.Active
, Module3 = t3.Active
FROM Module1 t1
FULL JOIN Module2 t2 ON t1.userid = t2.userid
FULL JOIN Module3 t3 ON t1.userid = t3.userid
WHERE t1.userid = '00000000-0000-0000-0000-000000000AB1'