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