繁体   English   中英

如何在一个表中使用条件并在另一个表中更新记录

[英]How do I use conditions in one table and update record in another table

CREATE TABLE candidate_subjects (
  id INT(10) PRIMARY KEY NOT NULL AUTO_INCREMENT,
  candidate_id INT(11),
  exam_type_id INT(10),
  subject_id INT(10),
  ca_score INT(11),
  exam_score INT(6),
  score_grade VARCHAR(10),
  date_created VARCHAR(10),
  date_modified TIMESTAMP
);

INSERT INTO `candidate_subjects` (`id`, `candidate_id`, `exam_type_id`, 
`subject_id`, `ca_score`, `exam_score`, `score_grade`, `date_created`, 
`date_modified`) VALUES
  (1, 2, 1, 32, 22, 61, NULL, '2017-02-01', '2017-08-28 13:10:33'),
  (2, 2, 1, 5, 21, 38, NULL, '2017-02-01', '2017-08-28 13:10:33'),
  (3, 2, 1, 14, 21, 51, NULL, '2017-02-01', '2017-08-28 13:10:33'),
  (4, 2, 1, 1, 19, 34, NULL, '2017-02-01', '2017-08-28 13:10:33'),
  (5, 2, 1, 2, 23, 39, NULL, '2017-02-01', '2017-08-28 13:10:33'),
  (6, 2, 1, 38, 20, 32, NULL, '2017-02-01', '2017-08-28 13:10:33'),
  (7, 2, 1, 53, 24, 47, NULL, '2017-02-01', '2017-08-28 13:10:33'),
  (8, 4, 1, 32, 19, 61, NULL, '2017-02-01', '2017-08-28 13:11:27'),
  (9, 4, 1, 5, 22, 41, NULL, '2017-02-01', '2017-08-28 13:11:27'),
  (10, 4, 1, 14, 20, 46, NULL, '2017-02-01', '2017-08-28 13:11:27'),
  (11, 4, 1, 1, 23, 37, NULL, '2017-02-01', '2017-08-28 13:11:27'),
  (12, 4, 1, 2, 21, 36, NULL, '2017-02-01', '2017-08-28 13:11:27'),
  (13, 4, 1, 38, 22, 34, NULL, '2017-02-01', '2017-08-28 13:11:27'),
  (14, 4, 1, 53, 24, 52, NULL, '2017-02-01', '2017-08-28 13:11:27'),
  (15, 5, 1, 32, 20, 62, NULL, '2017-02-01', '2017-08-28 13:11:44'),
  (16, 5, 1, 5, 22, 38, NULL, '2017-02-01', '2017-08-28 13:11:44');


CREATE TABLE candidates (
  id INT(11) PRIMARY KEY NOT NULL AUTO_INCREMENT,
  exam_no VARCHAR(15),
  surname VARCHAR(50),
  other_names VARCHAR(100),
  school_id INT(11),
  registration_completed INT(11),
  exam_scores_completed INT(5),
  remark VARCHAR(10)
);

INSERT INTO candidates (id, exam_no, surname, other_names, school_id,
registration_completed, exam_scores_completed, remark) VALUES
 (1, '1171052001', 'ABADO', 'MASENENGEN', 1052, 1, '1', ''),
 (2, '1170938001', 'AGBA', 'NGUHER', 938, 1, '1', ''), 
 (3, '1170071001', 'ABEE', 'SESUUR', 71, 1, '1', ''),
 (4, '1170938002', 'AHEN', 'REBECCA DOOSUUN', 938, 1, '1', '');

在上面,我有一个候选表和另一个候选表,用于分别存储候选细节和候选分数。 候选人主题具有主题的候选人分数。 注意数学的科目ID为2,英语ID为1。及格分数为40,即ca_score + exam_score的总数。 候选人评论的条件是:(数学<40或英语<40)的总分是'RESIT'。 否则,如果(数学> = 40并且英语> = 40)并且通过的总科目> = 6备注为'PASS'否则如果(数学的分数小于40并且在eng <40的分数)并且通过的总科目<6备注为'失败否则,如果(数学> 40并且eng> 40)且通过的总科目<6则评论失败。

以下是我编写的查询,但未提供预期的结果:

UPDATE candidates SET candidates.remark='FAIL' WHERE (select 
    count(candidate_subjects.id) AS total_pass from candidates, 
    candidate_subjects where candidates.id=candidate_subjects.candidate_id 
    and (candidate_subjects.ca_score + candidate_subjects.exam_score) >= 40) < 6

哪里什么? 当将子选择用于WHERE条件时,请将其视为IN()子句。 返回的值必须是条件逻辑中使用的值,在这种情况下为FK / ID。

您查询的最后一部分对我来说也没有意义。 这有意义吗?

UPDATE candidates SET candidates.remark = 'FAIL' 
WHERE candidates.id IN 
    (SELECT candidate_id FROM
        (SELECT candidate_id, count(candidate_subjects.id) AS total_pass
        FROM candidates, candidate_subjects
        WHERE candidates.id = candidate_subjects.candidate_id
        AND (candidate_subjects.ca_score + candidate_subjects.exam_score) >= 40)
    GROUP BY candidate_id
    HAVING total_pass = 6);

认为虽然存在一些语法错误,但希望对您有所帮助。 这些子选择可能需要别名... (...) AS sub1, 不记得了。

我将采用相反的方法,制作一个查询,以返回要更新的正确的candidate.id值。 然后在测试和运行该SQL的情况下,将其添加到您的更新中:

UPDATE candidates SET candidates.remark = 'FAIL' 
WHERE candidates.id IN (**THE SQL YOU WROTE AND TESTED RETURNING THE CORRECT IDS**)

使用一个简单的子查询。

UPDATE candidates
SET candidates.remark='FAIL'
WHERE (
      SELECT count(*) from candidate_subjects 
      WHERE candidate_id=candidates.id and (candidate_subjects.ca_score + candidate_subjects.exam_score) >= 40)
) < 6

要根据您的条件更新候选备注栏,它可能是一个复杂的查询,因为

update candidates c
join (

    select a.candidate_id,a.total_pass,
    e.ca_score + e.exam_score as english,
    m.ca_score + m.exam_score as maths
    from (select 
        count(id) AS total_pass ,candidate_id
        from candidate_subjects 
        where(ca_score + exam_score) >= 40
        group by candidate_id
    ) a
    left join candidate_subjects e on (a.candidate_id = e.candidate_id
                                       and e.subject_id = 1) /* english id */
    left join candidate_subjects m on (a.candidate_id = m.candidate_id
                                       and m.subject_id = 2) /* maths id */

) t on c.id = t.candidate_id
set c.remark = case 
    when t.maths < 40 or t.english < 40 then 'RESIT'
    when t.maths >= 40 and t.english >= 40 and t.total_pass >= 6 then 'PASS'
    when t.maths < 40 and t.english < 40 and t.total_pass < 6 then 'FAIL' 
    when t.maths > 40 and t.english > 40 and t.total_pass < 6 then 'FAIL'
    else c.remark
end;

演示

选择 *

选择编号

一些注意事项确保您的架构中具有以下索引

  • 应将候选人对象中的候选人ID设置为对候选人表的外键引用,并应为其建立索引

  • 在(ca_score + exam_score)上添加复合索引

  • 为subject_id添加索引

如果仍然遇到长时间执行的问题,则可以像join(....) part add这样批量运行中断查询

order by a.candidate_id asc
limit start,end // set these like 0,10000, 10000,10000, 20000,10000 .....

限制

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM