将排除某些记录的SQL

时间:2015-09-14 17:39:48

标签: sql sql-server tsql subquery common-table-expression

我正在为我们公司制作一份报告,这是一份速度报告。这是从我们的车队收集的数据。我们已经配置参数来标记谁正在根据他们驾驶的状态加速超过某个阈值,为该位置发布的速度限制等等。

我的SQL查询正在使用CTE。从我的CTE中选择时,我在其中包含了两个select语句。一个select语句用于满足或超过阈值要求的记录。我有一个名为SpeedingEvent的字段,这些记录的值为“Y”表示是。第二个select语句返回不满足或超过阈值的记录,SpeedingEvent值为“N”。这两个select语句的结果用UNION连接。

有点奇怪,但是我的公司希望能够看到发生的超速事件,即使它们没有达到阈值。我的问题是,其中一些排除的记录,SpeedingEvent值为“N”的记录,在SpeedingEvent =“Y”的数据集中没有匹配的记录,而且日期和车队编号匹配。

因此,当我生成我的SSRS报告时,我看到这些数据行被排除但与现有记录没有任何关系,这些数据符合阈值。

我已经尝试创建子查询,但是这不起作用,因为我收到一条错误消息,指出子查询返回的值超过1,并且在使用某些比较值时不允许这样做。

以下是我的代码示例。这不是一切,因为有许多领域正在被退回。

WITH cteSpeedReport([List of fields])
AS
(
SELECT DISTINCT
     [List of fields]
FROM
     [4 views that are being joined]
WHERE
     [Criteria for meeting threshold]
)
SELECT DISTINCT
     [List of Fields]
FROM (
SELECT DISTINCT DStartDate, DEndDate, DAssetID, DFleet, (DMax - DStateLimit) as DMaxOver, DEventStart, DEventEnd, DTotalEventSpeedingTime, EventSpeedingTimeInSeconds, DLimit, DStateLimit, DMax, EquipTypeQualifier, NDAssetID, NDFleet, NDDate, NDDriveTime, NDTotalDriveTimeInSeconds, SpeedPercentage, MilesSpeeding, CLatLong, CMapLink, CLocation, CMaxReportedSpeed, hlvl1no, hlvl1name, hlvl2no, hlvl2name, hlvl3no, hlvl3name, hlvl9no, hlvl9name, asset_id, asset_descr, equip_type, equiptype_code, insp_fleet, MaxSpdStartTime, MaxSpdEndTime, cast('Y' as char(1)) SpeedingEvent
from cteSpeedReport cteSR
where   
    (EquipTypeQualifier = 'Y' 
    AND ((CLocation = 'Michigan' AND 
            (DLimit = 70 AND DMax >= 70)
            OR (DLimit = 65 AND DMax >= 71.5)
            OR (DLimit = 60 AND DMax > 66)
            OR (DLimit <= 55 AND DMax >= (DLimit * 1.10)))
        OR (CLocation = 'Indiana' AND
            (DLimit = 70 AND DMax > 71.5)
            OR (DLimit = 65 AND DMax > 71.5)
            OR (DLimit <= 55 AND DMax >= (DLimit * 1.10)))))
    OR (DMax >= (DLimit * 1.10))
UNION
SELECT DISTINCT DStartDate, DEndDate, DAssetID, DFleet, (DMax - DStateLimit) as DMaxOver, DEventStart, DEventEnd, DTotalEventSpeedingTime, EventSpeedingTimeInSeconds, DLimit, DStateLimit, DMax, EquipTypeQualifier, NDAssetID, NDFleet, NDDate, NDDriveTime, NDTotalDriveTimeInSeconds, SpeedPercentage, MilesSpeeding, CLatLong, CMapLink, CLocation, CMaxReportedSpeed, hlvl1no, hlvl1name, hlvl2no, hlvl2name, hlvl3no, hlvl3name, hlvl9no, hlvl9name, asset_id, asset_descr, equip_type, equiptype_code, insp_fleet, MaxSpdStartTime, MaxSpdEndTime, cast('N' as char(1)) SpeedingEvent
from cteSpeedReport cteSRN
where   
    (EquipTypeQualifier = 'Y'
    AND ((CLocation = 'Michigan' AND 
            (DLimit = 70 AND DMax < 70)
            OR (DLimit = 65 AND DMax < 71.5)
            OR (DLimit = 60 AND DMax <= 66)
            OR (DLimit <= 55 AND DMax < (DLimit * 1.10)))
        OR (CLocation = 'Indiana' AND
            (DLimit = 70 AND DMax <= 71.5)
            OR (DLimit = 65 AND DMax <= 71.5)
            OR (DLimit <= 55 AND DMax < (DLimit * 1.10))))
    )
    OR (DMax < (DLimit * 1.10))
) a
where
    a.NDTotalDriveTimeInSeconds =
    (SELECT sr.NDTotalDriveTimeInSeconds FROM cteSpeedReport sr
    where sr.DStartDate = a.DStartDate and sr.DFleet = a.DFleet
    )
order by SpeedingEvent desc, DStartDate, hlvl9name, DFleet, DEventStart

非常感谢任何协助。

1 个答案:

答案 0 :(得分:0)

我认为问题出在WHERE子句中,子查询返回多个结果 - 给出。

WHERE a.NDTotalDriveTimeInSeconds =
  (SELECT sr.NDTotalDriveTimeInSeconds FROM cteSpeedReport sr
  WHERE sr.DStartDate = a.DStartDate AND sr.DFleet = a.DFleet )

您可以将其更改为MAX或SUM,或者为WHERE子句添加更多条件 - 具体取决于逻辑的工作方式。

WHERE a.NDTotalDriveTimeInSeconds =
  (SELECT SUM(sr.NDTotalDriveTimeInSeconds) FROM cteSpeedReport sr
  WHERE sr.DStartDate = a.DStartDate AND sr.DFleet = a.DFleet )

另一方面,您可以过滤一般结果,然后使用CASE语句确定 Y N ,而不是UNIONing这两种可能性。 strong> SpeedingEvent 专栏。

SELECT DISTINCT
     [List of Fields]
FROM (
    SELECT DISTINCT DStartDate, DEndDate, DAssetID, DFleet, (DMax - DStateLimit) as DMaxOver, DEventStart, DEventEnd, DTotalEventSpeedingTime, 
            EventSpeedingTimeInSeconds, DLimit, DStateLimit, DMax, EquipTypeQualifier, NDAssetID, NDFleet, NDDate, NDDriveTime, NDTotalDriveTimeInSeconds, 
            SpeedPercentage, MilesSpeeding, CLatLong, CMapLink, CLocation, CMaxReportedSpeed, hlvl1no, hlvl1name, hlvl2no, hlvl2name, hlvl3no, 
            hlvl3name, hlvl9no, hlvl9name, asset_id, asset_descr, equip_type, equiptype_code, insp_fleet, MaxSpdStartTime, MaxSpdEndTime, 
            CAST(
            CASE WHEN (CLocation = 'Michigan' AND (DLimit = 70 AND DMax < 70)
                        OR (DLimit = 65 AND DMax < 71.5)
                        OR (DLimit = 60 AND DMax <= 66)
                        OR (DLimit <= 55 AND DMax < (DLimit * 1.10)))
                    OR (CLocation = 'Indiana' AND (DLimit = 70 AND DMax <= 71.5)
                        OR (DLimit = 65 AND DMax <= 71.5)
                        OR (DLimit <= 55 AND DMax < (DLimit * 1.10)))
                THEN 'Y' ELSE 'N' END AS CHAR(1)) SpeedingEvent
    FROM cteSpeedReport cteSR
    WHERE   
        EquipTypeQualifier = 'Y' 
) a
WHERE a.NDTotalDriveTimeInSeconds = 
    (SELECT SUM(sr.NDTotalDriveTimeInSeconds) 
        FROM cteSpeedReport sr
        WHERE sr.DStartDate = a.DStartDate AND sr.DFleet = a.DFleet )
ORDER BY SpeedingEvent DESC, DStartDate, hlvl9name, DFleet, DEventStart