Oracle SQL:返回不带重复项的集合

Oracle SQL:返回不带重复项的集合,oracle,Oracle,使用以下查询对我有效,但我只需要为每个TPHONE.ID返回一个结果 我试图完成的是检查两个表中的三个日期字段,其中两个在TPHONE表中,一个在TPHONEREQUEST表中,并返回我在特定范围内找到日期的任何位置的TPHONE.ID。但是,如果任一表中有多个条目在日期范围内有一个或多个日期,我仍然只想返回TPHONE.ID一次 您可以将聚合和筛选与HAVING子句一起使用: 注: 这只返回TPHONE.ID,因为这似乎是您正在寻找的;如果需要更多列,则可以将它们添加到SELECT子句和GRO

使用以下查询对我有效,但我只需要为每个TPHONE.ID返回一个结果

我试图完成的是检查两个表中的三个日期字段,其中两个在TPHONE表中,一个在TPHONEREQUEST表中,并返回我在特定范围内找到日期的任何位置的TPHONE.ID。但是,如果任一表中有多个条目在日期范围内有一个或多个日期,我仍然只想返回TPHONE.ID一次


您可以将聚合和筛选与HAVING子句一起使用:

注:

这只返回TPHONE.ID,因为这似乎是您正在寻找的;如果需要更多列,则可以将它们添加到SELECT子句和GROUP BY子句中。注意,如果这些列的功能不依赖于TPHONE.ID,则这可能会更改分组条件

我使用表别名来缩短查询

我过去习惯于使用指定日期来生成正确的日期,而不是依赖数据库的默认格式,因为默认格式可能会在数据库和会话之间发生变化。这里假设您的日期格式为DD/MM/YYYY,也可以是MM/DD/YYYY


您可以使用ROW_NUMBER枚举具有相同ID的行,然后仅选择第一个实例:

SELECT TPHONE.ID,
       TPHONE.LOCATIONID,
       TPHONE.DLASTCHANGED,
       TPHONE.D02,
       TPHONEREQUEST.D03
FROM (
         SELECT TPHONE.ID,
                TPHONE.LOCATIONID,
                TPHONE.DLASTCHANGED,
                TPHONE.D02,
                TPHONEREQUEST.D03,
                ROW_NUMBER() over (PARTITION BY TPHONE.ID ORDER BY TPHONE.ID) as RN
         FROM TPHONE,
              TPHONEREQUEST
         WHERE TPHONE.ID = TPHONEREQUEST.DEVICEID
           AND TPHONE.ID IN
               (
                   SELECT TPHONE.ID
                   FROM TPHONE
                   WHERE TPHONE.DLASTCHANGED >= '7/1/2019' AND TPHONE.DLASTCHANGED < '10/1/2019'
                      OR TPHONE.D02 >= '7/1/2019' AND TPHONE.D02 < '10/1/2019'
                      OR TPHONEREQUEST.D03 >= '7/1/2019' AND TPHONEREQUEST.D03 < '10/1/2019'
               )
         ORDER BY TPHONE.LOCATIONID, TPHONE.ID
     )
WHERE RN = 1
但是为什么选择TPHONEREQUEST.D03?如果没有或多个电话请求与日期范围匹配,您会显示哪个电话请求?旁注:1您使用的连接语法在1992年的标准SQL中是多余的!请在…上使用来自tphone内部联接tphonerequest的显式联接。。。。2您依赖Oracle识别您的日期,这绝不能保证会发生。取决于数据库会话设置。改用日期文字,例如日期“2019-01-07”或日期“2019-07-01”,我甚至不知道它是什么。3您可以使用表别名来增强可读性。4混合和/或时,为了清晰起见,应使用括号。
SELECT p.ID,
FROM
    TPHONE p
    INNER JOIN TPHONEREQUEST t ON p.ID = r.DEVICEID
GROUP BY p.ID
HAVING
    MAX(
        CASE WHEN 
            (
                p.DLASTCHANGED >= TO_DATE('07/01/2019', 'DD/MM/YYYY') 
                AND p.DLASTCHANGED < TO_DATE('10/1/2019', 'DD/MM/YYYY')
            ) OR (
                p.D02 >= TO_DATE('07/01/2019', 'DD/MM/YYYY') 
                AND p.D02 < TO_DATE('10/1/2019', 'DD/MM/YYYY')
            ) OR (
                r.D03 >= TO_DATE('07/01/2019', 'DD/MM/YYYY') 
                AND r.D03 < TO_DATE('10/1/2019', 'DD/MM/YYYY')
            )
        THEN 1
        END
    ) = 1
SELECT TPHONE.ID,
       TPHONE.LOCATIONID,
       TPHONE.DLASTCHANGED,
       TPHONE.D02,
       TPHONEREQUEST.D03
FROM (
         SELECT TPHONE.ID,
                TPHONE.LOCATIONID,
                TPHONE.DLASTCHANGED,
                TPHONE.D02,
                TPHONEREQUEST.D03,
                ROW_NUMBER() over (PARTITION BY TPHONE.ID ORDER BY TPHONE.ID) as RN
         FROM TPHONE,
              TPHONEREQUEST
         WHERE TPHONE.ID = TPHONEREQUEST.DEVICEID
           AND TPHONE.ID IN
               (
                   SELECT TPHONE.ID
                   FROM TPHONE
                   WHERE TPHONE.DLASTCHANGED >= '7/1/2019' AND TPHONE.DLASTCHANGED < '10/1/2019'
                      OR TPHONE.D02 >= '7/1/2019' AND TPHONE.D02 < '10/1/2019'
                      OR TPHONEREQUEST.D03 >= '7/1/2019' AND TPHONEREQUEST.D03 < '10/1/2019'
               )
         ORDER BY TPHONE.LOCATIONID, TPHONE.ID
     )
WHERE RN = 1