Tsql 查看两个相关表的所有数据,即使某些数据未从表A注册到表B

Tsql 查看两个相关表的所有数据,即使某些数据未从表A注册到表B,tsql,sql-server-2012,Tsql,Sql Server 2012,我有两个sql server表,如下所示: [Management].[Person]( [PersonsID] [int] IDENTITY(1,1) NOT NULL, [FirstName] [nvarchar](50) NOT NULL, [LastName] [nvarchar](100) NOT NULL, [Semat] [nvarchar](50) NOT NULL, [Vahed] [nvarchar](50) NOT NULL, [Floo

我有两个sql server表,如下所示:

[Management].[Person](  
[PersonsID] [int] IDENTITY(1,1) NOT NULL,   
[FirstName] [nvarchar](50) NOT NULL, 
[LastName] [nvarchar](100) NOT NULL,    
[Semat] [nvarchar](50) NOT NULL,    
[Vahed] [nvarchar](50) NOT NULL,    
[Floor] [int] NOT NULL,     
[ShowInList] [bit] NOT NULL,    
[LastState] [nchar](10) NOT NULL)

第二个表中的PersonId是一个外键。 我在PersonCenter表上注册每个人进入系统的权限。 我想显示所有人在某个日期(PDate字段)输入stastus,如果输入系统的人显示其信息,如果没有,则显示null insted, 我尝试了以下查询:

select  * from [Management].[Person] left outer join [Management].[PersonEnters]
on [Management].[Person].[PersonsID] = [Management].[PersonEnters].[PersonID]
 where [Management].[PersonEnters].PDate = '1392/11/14'
但它只显示注册人在1392/11/14输入数据,其他人不显示任何信息,
我想为没有在'1392/11/14'上注册enter in Personents表的其他人显示此数据加上null或类似“NOT REGISTERED”的常量字符串。请帮助我。

从逻辑上讲,WHERE子句将在连接后应用。如果一些
Person
条目在
personeners
中没有匹配项,那么作为连接的结果,它们在
PDate
中将具有NULL,但是WHERE子句将过滤掉它们,因为比较
NULL='1392/11/14'
不会产生
true

select  * 
  from [Management].[Person] 
  left outer join [Management].[PersonEnters]
    on [Management].[Person].[PersonsID] = [Management].[PersonEnters].[PersonID]
   and [Management].[PersonEnters].PDate = '1392/11/14'
如果我正确理解了您的问题,您基本上希望外部联接到
Personners
的子集(其中
PDate='1392/11/14'
),而不是整个表。一种表达方式可能是这样的:

SELECT *
FROM Management.Person AS p
LEFT JOIN (
  SELECT *
  FROM Management.PersonEnters
  WHERE PDate = '1392/11/14'
) AS pe
ON p.Person.ID = pe.PersonID
;
如您所见,此查询非常明确地告诉服务器,在连接发生之前,应该从
Personners
派生特定子集,因为您希望指示与该特定子集的匹配,而不是与整个表的匹配

但是,同样的意图可以用更简洁的方式重写(没有派生表):


上述查询的效果是相同的,您将获得所有
Person
条目,只有当
personeners
具有
PDate='1392/11/14'

我在Management.personeners表中注册了所有条目时,才会从
personeners
获得匹配结果,如果我在星期一运行此查询,则查询结果中将忽略用户a,例如,如果在星期四所有人都输入,则我得到错误的结果,因此不清楚。解决这个问题。您的评论与“针对未注册的其他人”的评论不一致。如果某人在
Personents
中有条目,但在
1392/11/14
中没有条目,您的查询将根本不会返回该人,但OP似乎希望返回所有人。@AndriyM您确实从该评论中得到了这一点。这一切都是因为他想要所有的记录。OP需要写一个适当的问题。所有
Person
条目都应该返回的事实从一开始就让我觉得足够清楚,而评论只是证实了这一点。(我确实同意,作为一个整体,这个问题可能没有以最清晰的方式提出。)如果我想得到月度报告,我能做什么?我的意思是每天都要得到一份完整的名单,上面有没有在Personents注册的人。类似于每月的每日时间表,你可能追求类似的东西。而被接受的答案中的方法实际上就是你的解决方案。交叉连接的表将是
Person
和日期表,左侧连接的表将是
personeners
。如果您在实施过程中遇到问题,请随时发布新问题。(但一定要先自己解决——那样你会有更多的乐趣!)
SELECT *
FROM Management.Person AS p
LEFT JOIN (
  SELECT *
  FROM Management.PersonEnters
  WHERE PDate = '1392/11/14'
) AS pe
ON p.Person.ID = pe.PersonID
;
SELECT *
FROM Management.Person AS p
LEFT JOIN Management.PersonEnters AS pe
  ON p.Person.ID = pe.PersonID AND pe.PDate = '1392/11/14'
;