存在查询未产生预期结果的T-SQL案例

时间:2018-09-06 10:59:48

标签: sql sql-server tsql case exists

我整理了一个查询,该查询应显示在选定日期之前和之后具有事件的每条记录。添加了额外的一列,如果记录中有日期之前的事件,则将其设置为True / False,如果记录中第二个日期之后具有事件,则将其设置为True / False。

问题是我知道事件表中有记录,其中有事件在第一个日期之前而不是在第二个日期之后出现,但是它们没有出现在我的查询中。从这两个查询中得出的结果均为True。不知道我在做什么错。

SELECT DISTINCT DeviceName,dPhone,DSIMID,  Vehicles.reg, DeviceID,
CASE
WHEN EXISTS (SELECT eventID FROM [events] WHERE [events].sysdatetime < 
'2018-09-05 11:46:00.000')
THEN 'True' ELSE 'False' 
END AS [WasReportingBeforeDate],
CASE
WHEN EXISTS (SELECT eventID FROM [events] WHERE [events].sysdatetime > 
'2018-09-05 11:46:00.000')
THEN 'True' ELSE 'False' END AS [WasReportingAfterDate]
FROM [Devices]
INNER JOIN Vehicles ON Vehicles.DevID = Devices.DevID
INNER JOIN [events] ON Devices.DevID = [events].DeviceID;

当前输出示例为:

Z3243   1  1 AA05 AAA 1 True    True

预期输出:

Z3243   1  1 AA05 AAA 1 True    False

该记录没有第二个日期之前的数据,因此它应该返回false

3 个答案:

答案 0 :(得分:1)

我会将查询分为2个单独的查询,并使用union all将结果集再次返回在一起。如果需要标记来确定事件,然后再将其硬编码到以下查询中即可。

   ;WITH EventsBefore AS 
    (
    SELECT DISTINCT
           DeviceName,
           dPhone,
           DSIMID,
           Vehicles.reg,
           DeviceID,
    FROM [Devices]
         INNER JOIN Vehicles ON Vehicles.DevID = Devices.DevID
         INNER JOIN [events] ON Devices.DevID = [events].DeviceID
         INNER JOIN lastEvent ON Devices.DevID = lastEvent.devID;
    WHERE [events].sysdatetime < '2018-09-05 11:46:00.000'

    )

     ,EventsAfter AS 
    (
    SELECT DISTINCT
           DeviceName,
           dPhone,
           DSIMID,
           Vehicles.reg,
           DeviceID,
    FROM [Devices]
         INNER JOIN Vehicles ON Vehicles.DevID = Devices.DevID
         INNER JOIN [events] ON Devices.DevID = [events].DeviceID
         INNER JOIN lastEvent ON Devices.DevID = lastEvent.devID;
    WHERE WHERE [events].sysdatetime > '2018-09-05 11:46:00.000'

    )

    SELECT * FROM EventsBefore
    UNION ALL 
    SELECT * FROM EventsAfter

答案 1 :(得分:1)

您没有关联EXISTS,因此,如果表中存在与[events].sysdatetime > '2018-09-05 11:46:00.000'的任何记录,那么您的EXISTS将始终返回true。

您想要这样的东西:

...
CASE WHEN EXISTS (SELECT *
                  FROM [events] e2
                  WHERE e2.sysdatetime > '2018-09-05 11:46:00.000'
                  AND e2.eventID = e.eventID) --here
...
FROM [Devices] d
INNER JOIN Vehicles v ON b.DevID = d.DevID
INNER JOIN [events] e ON d.DevID = e.DeviceID;

答案 2 :(得分:0)

  1. 摆脱加入events的连接,随时删除多余的DISTINCT
  2. 将连接谓词放入现在丢失的子查询中

那样:

SELECT DeviceName,dPhone,DSIMID,  Vehicles.reg, DeviceID,
CASE
  WHEN EXISTS (SELECT 1 FROM [events] e 
    WHERE e.sysdatetime < '2018-09-05 11:46:00.000'
    AND e.DeviceID = Devices.DevID)
  THEN 'True' ELSE 'False' 
END AS [WasReportingBeforeDate],
CASE
  WHEN EXISTS (SELECT 1 FROM [events] e 
    WHERE e.sysdatetime > '2018-09-05 11:46:00.000'
    AND e.DeviceID = Devices.DevID)
THEN 'True' ELSE 'False' END AS [WasReportingAfterDate]
FROM [Devices]
INNER JOIN Vehicles ON Vehicles.DevID = Devices.DevID