我的问题的简化版本。我有2张桌子:
成绩:
id code_id score
1 11 100
2 12 20
3 13 40
4 14 70
5 15 90
6 16 10
7 17 30
8 18 50
代码:
id code
11
12
13
14
15
16 BBB
17 BBB
18 BBB
我需要生成一个Mysql SELECT查询,该查询将返回Scores表中代码表中没有相关代码的所有行,以及代码表中具有相同代码的行中的最高分数。
所需输出如下所示。分数ID为1-5,因为它们没有关联的代码,但只选择了ID 8,因为它是所有BBB代码分数的最高值。
id code_id score
1 11 100
2 12 20
3 13 40
4 14 70
5 15 90
8 18 50
我希望这是有道理的。我认为这将是一个简单的,但它让我感到困惑。我检查了[最大n组]标记问题的负载,大多数似乎只在执行GROUP BY和子选择时引用一个表而没有帮助。
非常感谢。
答案 0 :(得分:2)
也许我遗漏了您的要求但在两次查询之间使用UNION ALL可能更容易。
要获取null
表中具有codes
代码的行,您可以使用:
select s.id, s.code_id, s.score
from scores s
where exists (select id
from codes c
where s.code_id = c.id
and c.code is null)
然后,为了获得每个max(score)
的{{1}},您可以使用:
code
最后,您可以使用UNION ALL组合两个查询:
select s.id, s.code_id, s.score
from scores s
inner join codes c
on s.code_id = c.id
inner join
(
select c.code, max(s.score) score
from scores s
inner join codes c
on s.code_id = c.id
where c.code is not null
group by c.code
) m
on c.code = m.code
and s.score = m.score;
如果select s.id, s.code_id, s.score
from scores s
where exists (select id
from codes c
where s.code_id = c.id
and c.code is null)
union all
select s.id, s.code_id, s.score
from scores s
inner join codes c
on s.code_id = c.id
inner join
(
select c.code, max(s.score) score
from scores s
inner join codes c
on s.code_id = c.id
where c.code is not null
group by c.code
) m
on c.code = m.code
and s.score = m.score
group by c.code //To remove duplicates where the code and the score are equal
值为空字符串而不是code
,则编辑为旁注,然后您可以更改代码以使用null
(请参阅demo)。
答案 1 :(得分:1)
试试这个:
select s.*
from scores s join
(select coalesce(code, cast(id as varchar(32))) as codeid, max(id) as id
from codes c
group by coalesce(code, cast(id as varchar(32)))
) c
on s.code_id = c.id;
这个想法是总结代码表以获得每个代码的最大id,以及代码为NULL的每个id的单行。
以下显示结果(道歉,这是针对SQL Server但代码在那里非常相似):
declare @scores table (id int identity(1, 1), code_id int, score int);
insert into @scores(code_id, score)
select 11, 100 union all
select 12, 20 union all
select 13, 40 union all
select 14, 70 union all
select 15, 90 union all
select 16, 30 union all
select 17, 30 union all
select 18, 50;
declare @codes table (id int, code varchar(3));
insert into @codes(id, code)
select 11, NULL union all
select 12, NULL union all
select 13, NULL union all
select 14, NULL union all
select 15, NULL union all
select 16, 'BBB' union all
select 17, 'BBB' union all
select 18, 'BBB';
select s.*
from @scores s join
(select coalesce(code, cast(id as varchar(32))) as codeid, max(id) as id
from @codes c
group by coalesce(code, cast(id as varchar(32)))
) c
on s.code_id = c.id