SQL 连接并使用新列和基于其他列的值填充新表

问题描述 投票:0回答:2

我正在尝试一些 SQL 练习题,但我在回答一个问题时遇到了麻烦。

问题希望我返回一个包含[测试 ID、测试名称和测试难度] 的表。问题是我必须根据两个表之间的数据创建 [测试难度] 列(参与者分数在表 A 中,测试名称在表 B 中)。这些表共享测试 ID。

简而言之,我需要连接两个表,然后平均分数,然后创建新的测试难度列并根据平均分数填充它(例如,如果平均分数小于 20,则测试难度 =“hard” ).

目前,我已成功连接表格并计算平均分数,但我在创建此新列并根据条件填充的最后部分遇到了麻烦。有人可以帮忙吗?

注意,创建新表不是一个选项,所有操作都应该通过查询执行区完成。

代码如下:

表A

create table reports ( id integer not null, task_id integer not null, candidate varchar(40) not null, score integer not null, unique(id) );

表B

create table tasks ( id integer not null, name varchar(40) not null, unique(id) )

各表中的值

insert into reports values (13, 101, 'John Smith', 100);
insert into reports values (24, 123, 'Delaney Lloyd', 34);
insert into reports values (37, 300, 'Monroe Jimenez', 50);
insert into reports values (49, 101, 'Stanley Price', 45);
insert into reports values (51, 142, 'Tanner Sears', 37);
insert into reports values (68, 142, 'Lara Fraser', 3);
insert into reports values (83, 300, 'Tanner Sears', 0);

insert into tasks values (101, 'MinDist');
insert into tasks values (123, 'Equi');
insert into tasks values (142, 'Median');
insert into tasks values (300, 'Tricoloring');

我的代码:

select * 
from
(
select reports.task_id, 
tasks.name,
avg(reports.score) as average
from reports
join tasks
on tasks.id = reports.task_id
group by reports.task_id, tasks.name
) practice;
sql postgresql join case
2个回答
0
投票

一种选择(不是唯一的选择)是将现有查询放入公共表表达式中,并将其连接到更新语句。它看起来像:

alter table tasks add column "Test Difficulty" varchar(40);
with cte as
 (select reports.task_id, 
 tasks.name,
 avg(reports.score) as average
 from reports
 join tasks
 on tasks.id = reports.task_id
 group by reports.task_id, tasks.name)
update tasks
set "Test Difficulty" =
 CASE
  WHEN cte.average <= 20.0 THEN 'Hard'
  WHEN cte.average <= 40.0 THEN 'Medium'
  ELSE 'Easy'
 END
from cte
WHERE cte.task_id = tasks.id

您可以看到它在这里工作

with cte as (...)
只是包装您现有的查询。
update tasks set ... from cte where cte.task_id = tasks.id
将您的查询连接到您要更新的表。

case
语句决定您要填充的文本。因为您没有完全指定要求,所以我编造了一些数字/文本,但基本思想应该适用于您的实际问题。

另一种选择可能涉及在子查询中进行计算。 类似这样的事情


0
投票

有点不清楚您是否想将结果插入到某个地方,但这里有一些与您可以获得的查询尽可能接近的内容:

select
    practice.*,
    case
        when practice.average <= 20 then 'HARD'
        when practice.average > 20 and practice.average <= 40 then 'MEDIUM'
        else 'EASY'
    end as test_difficulty
from (
    select
        reports.task_id, 
        tasks.name,
        avg(reports.score) as average
    from reports
    join tasks on tasks.id = reports.task_id
    group by reports.task_id, tasks.name
) practice;

当然,您可以根据需要更改 CASE 语句。我正在使用“practice.average > 20 和practice.average <= 40" instead of BETWEEN, because BETWEEN is inclusive; this way each difficulty starts on .0(...)01 and ends on 0.
当然还有很多其他方法可以做到这一点 - CTE、函数等 - 但这似乎最接近您所描述的。

© www.soinside.com 2019 - 2024. All rights reserved.