oracle 带有group by子句的Minus查询给出不同的结果

i7uaboj4  于 2023-04-20  发布在  Oracle
关注(0)|答案(2)|浏览(100)

我已经检查了各种类似的问题,但找不到答案。我有2个相同的表(table 1和table 2)但它在不同的时间加载,一次在早上,另一次在晚上.我做了减去这些查询,得到0记录,这是期望的结果.但由于并行加载,我需要从table 1和table 2中获取唯一的记录。我尝试了rowid和rownumber方法,仍然在minus查询中获取记录。Approach 1(rowid):-

select data1,data2,data3,
    file_dt from table1
 where rowid IN ( select rid
                    from (select rowid rid, 
                                 row_number() over (partition by 
                         data2,data3
                                   order by file_dt DESC) rn
                            from table1)
                   where rn = 1)
minus
select data1,data2,data3,
    file_dt from table2
 where rowid IN ( select rid
                    from (select rowid rid, 
                                 row_number() over (partition by 
                         data2,data3
                                   order by file_dt DESC) rn
                            from table2)
                   where rn = 1)

我得到2条记录,但期望0条记录。Approach 2(row_number):-

select data1,data2,data3,
        file_dt,
       ROW_NUMBER() OVER(PARTITION BY data2,data3
                         ORDER BY file_dt desc) rn        
from table1)
WHERE rn = 1
minus
select data1,data2,data3,
        file_dt,
       ROW_NUMBER() OVER(PARTITION BY data2,data3
                         ORDER BY file_dt desc) rn        
from table2)
WHERE rn = 1

再次得到一些记录。任何帮助是感激!

vm0i2vca

vm0i2vca1#

这有点不清楚你在追求什么。你说“* 我需要从table1和table2中获取唯一的记录 *”,但随后又说你期望0行。为什么当你试图获取唯一的记录时会得到0行?
如果你需要从表中获取唯一的记录,那么先把0行的事情放在一边,这对你有用吗?用UNION ALL合并两个表,然后计算组合集的ROW_NUMBER,然后选择你想要的行。

select data1,data2,data3,file_dt
  from (select data1,data2,data3,file_dt,
               ROW_NUMBER() OVER (PARTITION BY data2,data3 ORDER BY file_dt DESC) seq
          from (select data1,data2,data3,file_dt from table1
                union all
                select data1,data2,data3,file_dt from table2))
 where seq = 1
zi8p0yeb

zi8p0yeb2#

我做了减去查询这些和得到0记录这是理想的结果
假设你做了这样的事情:

select data1, data2, data3, file_dt from table1
minus
select data1, data2, data3, file_dt from table2

这意味着在表1中没有也出现在表2中的数据。
这并不意味着这些表是相同的-可能表2中的数据没有出现在表1中。减法运算只会进行一种方式-from the docs,“第一个查询选择了所有不同的行,但第二个查询没有选择”。
如果table 2有相同data 1/2/3组合的附加数据,但日期较晚,则基本减号查询将看不到这些数据。

row_number() over (partition by data2,data3 order by file_dt DESC) as rn

那么这两个子查询只获取data 2/3组合的最近一行(基于file_dt)(但不包括data 1,它看起来很奇怪,但在这一点上并不重要)。
这意味着第二个子查询将拾取比第一个子查询中的记录更新的记录。
举一个简单的例子,如果表1中有以下数据:
| 数据1|数据2|数据3|文件_DT|
| --------------|--------------|--------------|--------------|
| 1|二|三|2023年1月1日|
| 二|三|四|2023年1月2日|
| 三|四|五|2023年1月3日|
在表2中:
| 数据1|数据2|数据3|文件_DT|
| --------------|--------------|--------------|--------------|
| 1|二|三|2023年1月1日|
| 二|三|四|2023年1月2日|
| 三|四|五|2023年1月3日|
| 二|三|四|2023年1月4日|
| 三|四|五|2023年1月5日|
第一个表中的所有三行也会出现在第二个表中,因此当您减去它们时,不会返回任何数据。
如果您查看两个表的rn计算:

select data1, data2, data3, file_dt,
  row_number() over (partition by data2,data3 order by file_dt DESC) as rn
from table1
数据1数据2数据3文件_DTRN
12023年1月1日1
2023年1月2日1
2023年1月3日1
select data1, data2, data3, file_dt
from (
  select data1, data2, data3, file_dt,
    row_number() over (partition by data2,data3 order by file_dt DESC) as rn
  from table1
)
where rn = 1
数据1数据2数据3文件_DT
12023年1月1日
2023年1月2日
2023年1月3日
select data1, data2, data3, file_dt,
  row_number() over (partition by data2,data3 order by file_dt DESC) as rn
from table2
数据1数据2数据3文件_DTRN
12023年1月1日1
2023年1月4日1
2023年1月2日
2023年1月5日1
2023年1月3日
select data1, data2, data3, file_dt
from (
  select data1, data2, data3, file_dt,
    row_number() over (partition by data2,data3 order by file_dt DESC) as rn
  from table2
)
where rn = 1
数据1数据2数据3文件_DT
12023年1月1日
2023年1月4日
2023年1月5日

你可以看到rn = 1上的过滤为两个子查询返回不同的行。当你有效地这样做时:

| 1 | 2 | 3 | 01-JAN-23 |
| 2 | 3 | 4 | 02-JAN-23 |
| 3 | 4 | 5 | 03-JAN-23 |

MINUS

| 1 | 2 | 3 | 01-JAN-23 |
| 2 | 3 | 4 | 04-JAN-23 |
| 3 | 4 | 5 | 05-JAN-23 |

唯一共同行是现在

| 1 | 2 | 3 | 01-JAN-23 |

所以minus操作只会删除这一行,查询将返回另外两个:
| 数据1|数据2|数据3|文件_DT|
| --------------|--------------|--------------|--------------|
| 二|三|四|2023年1月2日|
| 三|四|五|2023年1月3日|
fiddle

相关问题