Sql 需要为我的表中的每个人查找最大项代码值
我有一个具有多个术语代码值的人员列表。我需要找到每个有201930或201940记录的人的最大值。如果两者都有,我需要拿201930,比如鲍勃的案子。然后,我需要为每个使用该术语的人返回其他字段。只会返回红色记录。弗雷德不应该出现在输出中 这是我目前的查询,但它为Bob获取了201940记录。它的记录总数是正确的,但它得到了一些不正确的值Sql 需要为我的表中的每个人查找最大项代码值,sql,oracle,Sql,Oracle,我有一个具有多个术语代码值的人员列表。我需要找到每个有201930或201940记录的人的最大值。如果两者都有,我需要拿201930,比如鲍勃的案子。然后,我需要为每个使用该术语的人返回其他字段。只会返回红色记录。弗雷德不应该出现在输出中 这是我目前的查询,但它为Bob获取了201940记录。它的记录总数是正确的,但它得到了一些不正确的值 SELECT userid, term_code, race, gender FROM mytable a JOIN (
SELECT userid, term_code, race, gender
FROM mytable a JOIN (
SELECT userid, MAX(term_code) AS term_code
FROM mytable
WHERE term_code <= '201940'
GROUP BY userid
) b ON (a.userid = b.userid and a.term_code = b.term_code)
WHERE term_code IN ('201930', '201940');
在我看来,使用这一行似乎是合乎逻辑的,它为Bob获得了正确的值,但它将我的结果减少了约30%
WHERE term_code <= COALESCE ('201930','201940')
有什么建议吗?没有:
或者,如果您只需要userid和term_代码,则可以通过简单的聚合实现:
select userid, min(term_code) term_code
from mytable
where term_code in (201930, 201940)
group by userid
如果需要表中的整行,则可以加入表:
select m.*
from mytable m inner join (
select userid, min(term_code) term_code
from mytable
where term_code in (201930, 201940)
group by userid
) t on t.userid = m.userid and t.term_code = m.term_code
或具有行号窗口功能:
select t.userid, t.term_code, t.race, t.gender
from (
select m.*,
row_number() over (partition by userid order by term_code) rn
from mytable m
where m.term_code in (201930, 201940)
) t
where t.rn = 1
看。
结果:
请注意,术语_代码值与您感兴趣的值不同。
对于每个用户ID,使用求和分析函数根据您的条件对术语_代码进行排序。一旦计算出来,外部查询只会过滤掉内部查询中产生的排名第一的行。如果用户id都没有找到,那么预期的输出是什么?如果两者都有,比如Bob mean的情况,那么我需要取201930什么?如果没有找到术语代码,即一个人有201810和202010,该人员将不包括在输出中。他们需要201930或201940。如果一个人有201930和201940,那么只有201930应该显示在输出中。BobWHERE term_code Why sumcase when term_code in 202930,202940然后1 end?@forpas,当您同时拥有两个项目或两个项目都不可用时,它将过滤掉,如示例数据中所示-3个不同的测试案例。在取消注释之前,可以对外部查询进行注释,以测试不同的测试用例。这将以更复杂的方式返回行号返回的内容。
select t.userid, t.term_code, t.race, t.gender
from (
select m.*,
row_number() over (partition by userid order by term_code) rn
from mytable m
where m.term_code in (201930, 201940)
) t
where t.rn = 1
> USERID | TERM_CODE | RACE | GENDER
> :----- | --------: | :--- | :-----
> Bob | 201930 | null | null
> Tim | 201940 | null | null
with t (USERID, term_code ) as (
select 'Bob', 201601 from dual union all
select 'Bob', 201605 from dual union all
select 'Bob', 201609 from dual union all
select 'Bob', 202930 from dual union all
select 'Bob', 202940 from dual union all
select 'Bob', 202950 from dual union all
select 'Tom', 202940 from dual union all
select 'Tom', 201605 from dual union all
select 'Tom', 201609 from dual union all
select 'Mac', 201601 from dual union all
select 'Mac', 201605 from dual union all
select 'Mac', 201609 from dual
)
select userid, term_code from
(
SELECT t.*
, sum(case when term_code in (202930, 202940) then 1 end) over (partition by userid order by term_code) rnk
FROM t
)
where rnk = 1
USE TERM_CODE
--- ----------
Bob 202930
Tom 202940