2014-10-09 87 views
0

我遇到问题。SQL - SELECT子查询AS BIT值用于EXIST检查

我试图得到一个BIT值来检查一个人是否昨晚晚上10点到午夜进入了大楼。当我自己运行子查询代码时,它给了我需要的结果。由于我正在使用SSRS2008,因此我需要将所有结果存储在相同的存储过程中。

所以问题是,它给了我一些比较正确的值,对于那些显然是错误的,它给出错误的,对于那些显然是真的,它给出了正确的错误。但对于中间的人(白班,谁离开在23)它给出了一些随机结果..

有没有人有线索?

SELECT DISTINCT TOP 200 
    Events.LoggedTime, 
    PTUsers.Name, 
    PTDoors.PTDoorsID, 
    PTUsers.AccessLevel, 
    CAST(CASE 
      WHEN EXISTS (SELECT Events.LoggedTime 
         FROM Events 
         INNER JOIN PTUsers AS PTUsers_1 ON Events.GlobalIndex1 = PTUsers.GlobalRecord 
         INNER JOIN PTDoors AS PTDoors_1 ON Events.RecordIndex2 + 1 = PTDoors.Address 
         WHERE (DATEPART(day, Events.LoggedTime) = DATEPART(day, GETDATE() - 1)) 
          AND (DATEPART(hour, Events.LoggedTime) IN (22, 23)) 
          AND (PTDoors_1.PTDoorsID = 14)) THEN 1 ELSE 0 END AS BIT) AS Night 
FROM   
    Events 
INNER JOIN 
    PTUsers ON Events.GlobalIndex1 = PTUsers.GlobalRecord 
INNER JOIN 
    PTDoors ON Events.RecordIndex2 + 1 = PTDoors.Address 
WHERE  
    (PTUsers.Panel = 0) 
    AND (PTDoors.Panel = 0) 
    AND (PTDoors.PTDoorsID = 14) 
    AND (DATEPART(day, Events.LoggedTime) = DATEPART(day, GETDATE()) - 1) 
    AND (PTUsers.AccessLevel IN (3)) 
ORDER BY 
    Events.LoggedTime DESC 
+0

你是什么意思随机。您是否获得每个用户实例或不同值的相同值。似乎每次用户重复时,总是会有相同的1或0的值,除非您从前一天或第二天拉出记录,但是,我不知道发生了什么。 – 2014-10-09 17:39:31

+0

随机混合。对于大多数早上抵达并在下午离开的人来说,这是真实的和虚假的。 对于大多数到达第22或第23小时并在早上离开的人来说,这是正确的。对于下午抵达并在22或23小时候离开的人来说,它是真实的和虚假的。这不可能。他们都使用相同的门。 其中一些甚至在6点或7点之后还没有注册价值..我也偶尔得到了真实。 – 2014-10-10 10:32:25

+0

该代码的目的是检查人员在给定日期何时到达,但是要检查他/她是否在前一天晚上进行了换班。 我这样做是为了避免误报。我还有一些代码可以根据到达时间分配人员进行轮班,但是对于上班时间,它需要检查此人是否在前一天进行了夜班。 我们发生了人员走出的事件,然后又回来了,因为他们忘记了一些事情,然后又出来了,但他们被分配到了早班,并且被标记为迟到:所以位检查将用于ssrs来验证 – 2014-10-10 10:36:47

回答

0

我不认为你需要一个CAST,因为你明确地定义晚上受了一点设置为EXISTS()的结果,这是一个有点。我删除了错误的查询。

我看到你的问题。您在子查询中没有为连接约束使用正确的表别名。

它应该是:

INNER JOIN PTUsers AS PTUsers_1 ON Events.GlobalIndex1 = PTUsers_1.GlobalRecord 
INNER JOIN PTDoors AS PTDoors_1 ON Events.RecordIndex2 + 1 = PTDoors_1.Address 

此外,检查并确保您使用的是您的加入正确的价值观。我会改变以下的测试。

FROM Events Events_2 
INNER JOIN PTUsers AS PTUsers_1 ON Events_2.GlobalIndex1 = PTUsers_1.GlobalRecord 
INNER JOIN PTDoors AS PTDoors_1 ON Events_2.RecordIndex2 + 1 = PTDoors_1.Address 
0

@lrd我做我脱离的铸造你的建议更正, 感谢您指出了表的别名:)

,所以现在我得到的BIT列。但现在问题是我得到所有“1”的结果。 让我感到困惑的是,子查询的工作原理就像它自己的查询一样。它会返回一天,并在给定的时间内显示该门上的条目。

现在我试图比较同一个人的信息,意思是 - 我在列表中看到一个人,昨天早上6点到达,检查该人是否也在22 &午夜之前抵达并返回显示该值。

SELECT DISTINCT TOP 200 Events.LoggedTime, PTUsers.Name, PTDoors.PTDoorsID, PTUsers.AccessLevel, CASE WHEN EXISTS 
          (SELECT  Events.LoggedTime 
          FROM   Events INNER JOIN 
                PTUsers AS PTUsers_1 ON Events.GlobalIndex1 = PTUsers_1.GlobalRecord INNER JOIN 
                PTDoors AS PTDoors_1 ON Events.RecordIndex2 + 1 = PTDoors_1.Address 
          WHERE  (DATEPART(day, Events.LoggedTime) = DATEPART(day, GETDATE() - 1)) AND (DATEPART(hour, Events.LoggedTime) IN (22, 23)) AND 
                (PTDoors_1.PTDoorsID = 14)) THEN 1 ELSE 0 END AS BIT 
FROM   Events INNER JOIN 
         PTUsers ON Events.GlobalIndex1 = PTUsers.GlobalRecord INNER JOIN 
         PTDoors ON Events.RecordIndex2 + 1 = PTDoors.Address 
WHERE  (PTUsers.Panel = 0) AND (PTDoors.Panel = 0) AND (PTDoors.PTDoorsID = 14) AND (DATEPART(day, Events.LoggedTime) = DATEPART(day, GETDATE()) 
         - 1) AND (PTUsers.AccessLevel IN (3)) 
ORDER BY Events.LoggedTime DESC 
+0

在子查询中将'getdate()'固定为-2。 仍然只有1位 – 2014-10-10 10:50:54

+0

我用另一种可能的解决方案更新了我的答案 – 2014-10-10 17:37:18