如何获取另一个 table 中不存在的值,忽略最近日期的重复值
How to get values that do not exist in another table, ignoring duplicate values with the most recent date
如何在给定 ff 的情况下仅获取 table A 中不存在于 table B 中的 LEVEL_20 值。场景:
- 如果CODE_LEVELlevel_20的PRIZE在A中有相同的LEVEL_20值,忽略它!
如果有多个PRIZE值,将值与B中的最大日期进行比较
Table A
ALIAS LEVEL_20 POINTS DATE
Jbax 300 325 6/20/2018
Cvg2 100 103 6/20/2018
Deg1 200 281 6/20/2018
Table B
ALIAS CODE_LEVEL PRIZE DATE
Jbax Level_20 500 1/15/2017
Jbax Level_10 200 3/20/2017
Cvg2 Level_20 100 4/5/2018
Deg1
Cvg2 Level_20 50 2/1/2017
TABLE C
ALIAS NAME
Jbax Jessie
Cvg2 Carol
Deg1 Danny
Expected Output:
NAME RANKING
Danny 200
Jessie 300
My (wrong) code:
select name,
case when points between 101 and 200 then '100'
when points between 201 and 300 then '200'
when points between 301 and 400 then '300'
end ranking
from c left outer join b on b.alias = c.alias
left outer join a on a.alias = c.alias
where do not exists
(select 'x' from b where b.code_level = 'level_20'
and b.prize <> a.level_20
and b.alias = a.alias
and b.date =
(select max(b2.date)
from b b2 where b2.alias = b.alias
and b2.code_level = b.code_level)
)
使用此查询而不包括 table b
就足够了,这取决于您的预期输出并取决于 tables 中的数据:
with a(ALIAS, LEVEL_20, POINTS, "DATE") as
(
select 'Jbax',300,325,date'2018-06-20' from dual union all
select 'Cvg2',100,103,date'2018-06-20' from dual union all
select 'Deg1',200,281,date'2018-06-20' from dual
), b(ALIAS, CODE_LEVEL, PRIZE, "DATE") as
(
select 'Jbax','Level_20',500,date'2017-01-15' from dual union all
select 'Jbax','Level_10',200,date'2017-03-20' from dual union all
select 'Cvg2','Level_20',100,date'2017-04-05' from dual union all
select 'Deg1',null,null,null from dual union all
select 'Cvg2','Level_20',50,date'2017-02-01' from dual
), c(ALIAS,NAME) as
(
select 'Jbax','Jessie' from dual union all
select 'Cvg2','Carol' from dual union all
select 'Deg1','Danny' from dual
)
select c.name, a.level_20
from c
join a on a.alias = c.alias
where (a.alias,a.level_20) not in
(select a.alias,b.prize
from a
join b on b.prize = a.level_20 and b.code_level = 'Level_20');
NAME LEVEL_20
------ --------
Jessie 300
Danny 200
P.S。 tableb
中没有多个PRIZE值
这应该会给您预期的结果:
with get_max_value as
(
select b2.*, max(b2."DATE") over (partition by b2.ALIAS) mdate from b b2
)
select my_c.name, my_a.level_20
from c my_c join a my_a on my_a.alias = my_c.alias
where (my_a.alias,my_a.level_20) not in
(select a2.alias, gmv.prize
from a a2 join get_max_value gmv on gmv.prize = a2.level_20
and gmv.code_level = 'Level_20'
WHERE gmv."DATE" = gmv.mdate);
我认为你的意思是相同的别名而不是相同的价格。在我看来,相同的价格毫无意义,所以我只是按相同的别名分组。如果您需要最高价格,那么其他答案中的建议就可以了。
此查询在 table b
:
中添加排序
select a.alias, a.level_20, c.name, b.code_level, b.prize, b.date_,
row_number() over (partition by a.alias, c.name order by b.date_ desc) rn
from a join c on c.alias = a.alias
left join b on b.alias = a.alias and b.code_level = 'Level_20'
结果:
ALIAS LEVEL_20 NAME CODE_LEVEL PRIZE DATE_ RN
----- ---------- ------ ---------- ---------- ----------- ----------
Cvg2 100 Carol Level_20 100 2017-04-05 1
Cvg2 100 Carol Level_20 50 2017-02-01 2
Deg1 200 Danny 1
Jbax 300 Jessie Level_20 500 2017-01-15 1
pqrs 100 Peter Level_20 200 2017-04-05 1
pqrs 100 Peter Level_20 100 2017-02-01 2
所以现在您只能获取这些 最新 (rn = 1
) 并且奖品为空或奖品不同于 a.level_20
:[=17 的行=]
select name, level_20
from (
select a.alias, a.level_20, c.name, b.code_level, b.prize, b.date_,
row_number() over (partition by a.alias, c.name order by b.date_ desc) rn
from a join c on c.alias = a.alias
left join b on b.alias = a.alias and b.code_level = 'Level_20')
where rn = 1 and (prize is null or prize <> level_20)
dbfiddle demo(我在那里加了一行)
如何在给定 ff 的情况下仅获取 table A 中不存在于 table B 中的 LEVEL_20 值。场景:
- 如果CODE_LEVELlevel_20的PRIZE在A中有相同的LEVEL_20值,忽略它!
如果有多个PRIZE值,将值与B中的最大日期进行比较
Table A
ALIAS LEVEL_20 POINTS DATE Jbax 300 325 6/20/2018 Cvg2 100 103 6/20/2018 Deg1 200 281 6/20/2018
Table B
ALIAS CODE_LEVEL PRIZE DATE
Jbax Level_20 500 1/15/2017
Jbax Level_10 200 3/20/2017
Cvg2 Level_20 100 4/5/2018
Deg1
Cvg2 Level_20 50 2/1/2017
TABLE C
ALIAS NAME
Jbax Jessie
Cvg2 Carol
Deg1 Danny
Expected Output:
NAME RANKING
Danny 200
Jessie 300
My (wrong) code:
select name,
case when points between 101 and 200 then '100'
when points between 201 and 300 then '200'
when points between 301 and 400 then '300'
end ranking
from c left outer join b on b.alias = c.alias
left outer join a on a.alias = c.alias
where do not exists
(select 'x' from b where b.code_level = 'level_20'
and b.prize <> a.level_20
and b.alias = a.alias
and b.date =
(select max(b2.date)
from b b2 where b2.alias = b.alias
and b2.code_level = b.code_level)
)
使用此查询而不包括 table b
就足够了,这取决于您的预期输出并取决于 tables 中的数据:
with a(ALIAS, LEVEL_20, POINTS, "DATE") as
(
select 'Jbax',300,325,date'2018-06-20' from dual union all
select 'Cvg2',100,103,date'2018-06-20' from dual union all
select 'Deg1',200,281,date'2018-06-20' from dual
), b(ALIAS, CODE_LEVEL, PRIZE, "DATE") as
(
select 'Jbax','Level_20',500,date'2017-01-15' from dual union all
select 'Jbax','Level_10',200,date'2017-03-20' from dual union all
select 'Cvg2','Level_20',100,date'2017-04-05' from dual union all
select 'Deg1',null,null,null from dual union all
select 'Cvg2','Level_20',50,date'2017-02-01' from dual
), c(ALIAS,NAME) as
(
select 'Jbax','Jessie' from dual union all
select 'Cvg2','Carol' from dual union all
select 'Deg1','Danny' from dual
)
select c.name, a.level_20
from c
join a on a.alias = c.alias
where (a.alias,a.level_20) not in
(select a.alias,b.prize
from a
join b on b.prize = a.level_20 and b.code_level = 'Level_20');
NAME LEVEL_20
------ --------
Jessie 300
Danny 200
P.S。 tableb
这应该会给您预期的结果:
with get_max_value as
(
select b2.*, max(b2."DATE") over (partition by b2.ALIAS) mdate from b b2
)
select my_c.name, my_a.level_20
from c my_c join a my_a on my_a.alias = my_c.alias
where (my_a.alias,my_a.level_20) not in
(select a2.alias, gmv.prize
from a a2 join get_max_value gmv on gmv.prize = a2.level_20
and gmv.code_level = 'Level_20'
WHERE gmv."DATE" = gmv.mdate);
我认为你的意思是相同的别名而不是相同的价格。在我看来,相同的价格毫无意义,所以我只是按相同的别名分组。如果您需要最高价格,那么其他答案中的建议就可以了。
此查询在 table b
:
select a.alias, a.level_20, c.name, b.code_level, b.prize, b.date_,
row_number() over (partition by a.alias, c.name order by b.date_ desc) rn
from a join c on c.alias = a.alias
left join b on b.alias = a.alias and b.code_level = 'Level_20'
结果:
ALIAS LEVEL_20 NAME CODE_LEVEL PRIZE DATE_ RN
----- ---------- ------ ---------- ---------- ----------- ----------
Cvg2 100 Carol Level_20 100 2017-04-05 1
Cvg2 100 Carol Level_20 50 2017-02-01 2
Deg1 200 Danny 1
Jbax 300 Jessie Level_20 500 2017-01-15 1
pqrs 100 Peter Level_20 200 2017-04-05 1
pqrs 100 Peter Level_20 100 2017-02-01 2
所以现在您只能获取这些 最新 (rn = 1
) 并且奖品为空或奖品不同于 a.level_20
:[=17 的行=]
select name, level_20
from (
select a.alias, a.level_20, c.name, b.code_level, b.prize, b.date_,
row_number() over (partition by a.alias, c.name order by b.date_ desc) rn
from a join c on c.alias = a.alias
left join b on b.alias = a.alias and b.code_level = 'Level_20')
where rn = 1 and (prize is null or prize <> level_20)
dbfiddle demo(我在那里加了一行)