从多个表中选择一列并作为一个表返回

时间:2015-09-17 13:28:04

标签: sql-server

我在数据库中有一个简单的模块基础设置表,如下所示:

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。

4 个答案:

答案 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'