如何编写oracle SQL查询以特定顺序获取匹配和不匹配的行对(基于键列)
Posted
技术标签:
【中文标题】如何编写oracle SQL查询以特定顺序获取匹配和不匹配的行对(基于键列)【英文标题】:How to write oracle SQL query to get matching and non-matching pair of rows (on the basis of key columns) in a certain order 【发布时间】:2020-07-06 10:53:40 【问题描述】:我有以下示例数据:
ID BOOK_NAME AUTHOR YEAR PAGE_COUNT PRICE BUCKET
1 Book1 A1 2001 450 44 1
2 Book2 A2 2002 550 50 1
3 Book1 A1 2001 450 44 2
4 Book3 A3 2003 350 38 1
5 Book2 A2 2002 550 50 2
6 Book3 A3 2003 350 38 2
7 Book4 A4 2006 400 60 1
8 Book4 A4 2006 410 60 2
9 Book5 A5 1999 600 58 1
10 Book6 A6 2004 650 76 2
上面的示例数据包含来自两个存储桶 - 1 和 2 的书籍。要求以显示两个存储桶之间匹配和不匹配书籍的方式对书籍进行排序,即一本书被称为 MATCHED 如果它存在于两个存储桶中(通过匹配关键列 - BOOK_NAME、AUTHOR、YEAR、PAGE_COUNT、PRICE),否则为 UNMATCHED。即使单个列在任何一对的两个存储桶之间都不匹配,这本书也被视为 UNMATCHED。以下是上述输入的预期输出。
STATUS ID BOOK_NAME AUTHOR YEAR PAGE_COUNT PRICE BUCKET
MATCHED 2 Book2 A2 2002 550 50 1
MATCHED 5 Book2 A2 2002 550 50 2
MATCHED 1 Book1 A1 2001 450 44 1
MATCHED 3 Book1 A1 2001 450 44 2
MATCHED 4 Book3 A3 2003 350 38 1
MATCHED 6 Book3 A3 2003 350 38 2
UNMATCHED 7 Book4 A4 2006 400 60 1
UNMATCHED 9 Book5 A5 1999 600 58 1
UNMATCHED 10 Book6 A6 2004 650 76 2
UNMATCHED 8 Book4 A4 2006 410 60 2
另外-
-
匹配的货币对应按 PRICE 列排序,即价格最高的货币对应排在第一位。
在列表的不匹配部分中,项目应按存储桶排序,即所有存储桶 1 不匹配的项目应放在一起,然后所有存储桶 2 不匹配的项目应出现。
对于未匹配部分中的每个存储桶,然后应按 PRICE 列对项目进行进一步排序,即价格最高的一对应排在第一位。
所以,问题在于按节规则对数据集进行排序。请提供单个查询解决方案的帮助,我知道可以通过获取数据并以任何编码语言(如 Java)应用逻辑来轻松完成。但基于设计要求,我对基于 SQL 的简单解决方案感兴趣。请帮忙。
【问题讨论】:
【参考方案1】:您可以使用窗口函数。假设这些书在桶中内没有重复:
select (case when count(*) over (partition by BOOK_NAME, AUTHOR, YEAR, PAGE_COUNT, PRICE) = 2
then 'Matched' else 'Unmatched'
end) as status,
t.*
from t
order by status,
(case when count(*) over (partition by BOOK_NAME, AUTHOR, YEAR, PAGE_COUNT, PRICE) = 2 then price end) desc,
bucket
【讨论】:
【参考方案2】:感谢戈登的回复!它给了我解决问题的方向。我在下面做了一些调整以满足我的需要。
select (case when count(*) over (partition by BOOK_NAME, AUTHOR, YEAR, PAGE_COUNT, PRICE) = 2
then 'Matched' else 'Unmatched'
end) as status,
t.*
from t
order by status,
(case when status = 'Matched' then price end) desc,
(case when status = 'Unmatched' then bucket end),
(case when status = 'Matched' then BOOK_NAME end),
(case when status = 'Matched' then AUTHOR end),
(case when status = 'Matched' then YEAR end),
(case when status = 'Matched' then PAGE_COUNT end),
(case when status = 'Matched' then bucket end),
(case when status = 'Unmatched' then price end) desc
【讨论】:
以上是关于如何编写oracle SQL查询以特定顺序获取匹配和不匹配的行对(基于键列)的主要内容,如果未能解决你的问题,请参考以下文章