如何在Oracle sql中按结果分组使用案例
我有一个包含以下列的表格如何在Oracle sql中按结果分组使用案例,sql,oracle,join,group-by,case,Sql,Oracle,Join,Group By,Case,我有一个包含以下列的表格 person_id Person_Name Telephone_No City Email_Id Insert_TS 还有其他一些列,如备用名称等。 在该表中,每当在任何特定行中有任何更新时,都会插入一行。比如说 P01 Radhe 0112311231 Bia b@b.com 09-NOV-2012 15:24:38 P01 Radhe Null Bia a@b.com 30-APR-2014 21:26:51 P02 Shayam 456897845
person_id Person_Name Telephone_No City Email_Id Insert_TS
还有其他一些列,如备用名称等。
在该表中,每当在任何特定行中有任何更新时,都会插入一行。比如说
P01 Radhe 0112311231 Bia b@b.com 09-NOV-2012 15:24:38
P01 Radhe Null Bia a@b.com 30-APR-2014 21:26:51
P02 Shayam 456897845 Albi s@b.com 30-APR-2014 14:36:03
P03 Radha Null xyz s1@b.com 31-APR-2014 14:36:03
意味着,电话字段中很少有记录包含null,但所有其他字段都有数据
我想显示person\u id person\u Name Telephone\u No City Email\u id列,这样,如果有任何一行包含对应于一个person\u id的Telephone\u No value not null,那么应该显示该行的最新记录
其他的
应显示该人员的最新记录
要汇总显示具有最新电话号码的唯一人员id,对于没有电话号码的人员,不应显示最新记录
我试着这样做:
获取具有最新电话号码的唯一个人id--A
获取所有具有最新记录的唯一个人id--B
将数据显示为(B-A)+A
但这需要太多时间,而且似乎效率不高。
请建议查询以更快地获取记录
其他可能的方法是使用分组结果上的case语句,如按人员id分组值,如果每个组中都有电话号码,则显示具有最新值的电话号码,否则显示组中的最新条目是否仅显示每个人的最后一行?假设person\u id,Insert\u TS是唯一的:
select person_id, max(Insert_TS)
from T
group by person_id
然后将其与表连接以获取所有信息
对于oracle的最新版本,您可以使用row_number(),如中所示
我不确定我是否完全理解,但这里有一个尝试。我从SQLFIDLE for Oracle中得到错误,并且我自己没有访问Oracle的权限,因此以下内容在DB2V10.5上进行了测试。我删除了几列,简化了一些。此外,时间戳与您的时间戳不同:
with tmp as (select PERSON_ID, PERSON_NAME, TELEPHONE_NO, INSERT_TS
,row_number() over (partition by person_id
order by insert_ts desc) as rn
from t)
select * from tmp x
where rn = (
select coalesce(min(rn),1)
from tmp y
where x.person_id = y.person_id
and y.TELEPHONE_NO is not null
);
PERSON_ID PERSON_NAME TELEPHONE_NO INSERT_TS RN
--------- ----------- --------------- -------------------------- --------------------
P01 Radhe 011231123109 2012-05-22-14.27.35.037579 2
P02 Shayam 456897845 2014-05-22-14.27.35.037579 1
P03 Radha - 2014-06-22-14.27.35.037579 1
3 record(s) selected.
感谢回复,最新一行可能不包含前几行中插入的同一个人id的信息。例如,如果电子邮件id发生更改而不是电话号码,则最新的一行可能不包含有关电话号码的详细信息,因此每列的最后一个非空值就足够了?否,因为没有电话号码值的人很少
with tmp as (select PERSON_ID, PERSON_NAME, TELEPHONE_NO, INSERT_TS
,row_number() over (partition by person_id
order by insert_ts desc) as rn
from t)
select * from tmp x
where rn = (
select coalesce(min(rn),1)
from tmp y
where x.person_id = y.person_id
and y.TELEPHONE_NO is not null
);
PERSON_ID PERSON_NAME TELEPHONE_NO INSERT_TS RN
--------- ----------- --------------- -------------------------- --------------------
P01 Radhe 011231123109 2012-05-22-14.27.35.037579 2
P02 Shayam 456897845 2014-05-22-14.27.35.037579 1
P03 Radha - 2014-06-22-14.27.35.037579 1
3 record(s) selected.