我尝试了几种不同的查询来将结果集限制在所需的范围内,但是我一直缺少一些东西。
在我的示例中,我有三种文档类型:注册,标题和凭证。如果ASSET_ID的记录为DOC TYPE =标题,但又有一条记录为DOC_TYPE = Voucher,则我不想显示Voucher行。但是,如果ASSET_ID仅具有凭证行,那么我想显示记录。第三个条件是,如果同一个asset_id具有两个或更多凭证行,那么我只想显示一个。
以下是使用虚拟数据的示例:
ASSET_ID DOC_TYPE State
101 Registration TX
102 Title AL
103 Title NY
104 Title CA
104 Voucher
105 Title CA
106 Voucher
106 Title MD
107 Voucher
107 Voucher
我想到了两种方法。我的第一个想法是编写一个查询,将其从结果中完全删除:
SELECT * FROM assets WHERE doc_type <> 'Voucher'
然后我要去UNION另一个查询,该查询只提取凭证doc_type:
SELECT asset_id, doc_type, state FROM assets WHERE doc_type <> 'Voucher'
UNION
SELECT * FROM (SELECT DISTINCT(asset_id), doc_type, state FROM assets WHERE
doc_type = 'Voucher')
我最终要做的是编写联合查询来引用原始查询,以查找满足第一个查询中未包含的条件的值。但这感觉写查询的方式效率极低:
SELECT asset_id, doc_type, state FROM assets WHERE doc_type <> 'Voucher'
UNION
SELECT DISTINCT(asset_id), doc_type, state FROM assets WHERE doc_type =
'Voucher' AND asset_id NOT IN (SELECT asset_id, doc_type, state FROM assets
WHERE doc_type <> 'Voucher')
以上方法有效,但是我假设有一种比我建议的方法更清洁的方法来处理此问题。有什么建议吗?
答案 0 :(得分:1)
也许是这样?
SQL> with assets (asset_id, doc_type, state) as
2 (select 101, 'registration', 'tx' from dual union all
3 select 102, 'title' , 'al' from dual union all
4 select 103, 'title' , 'ny' from dual union all
5 select 104, 'title' , 'ca' from dual union all
6 select 104, 'voucher' , null from dual union all
7 select 105, 'title' , 'ca' from dual union all
8 select 106, 'voucher' , null from dual union all
9 select 106, 'title' , 'md' from dual union all
10 select 107, 'voucher' , null from dual union all
11 select 107, 'voucher' , null from dual
12 ),
13 inter as
14 (select asset_id, doc_type, state,
15 row_number() over (partition by asset_id
16 order by decode(doc_type, 'title', 1, 'voucher', 2)) rn
17 from assets
18 )
19 select asset_id, doc_type, state
20 from inter
21 where rn = 1
22 order by asset_id;
ASSET_ID DOC_TYPE ST
---------- ------------ --
101 registration tx
102 title al
103 title ny
104 title ca
105 title ca
106 title md
107 voucher
7 rows selected.
SQL>