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

时间:2017-09-22 17:18:59

标签: php mysql

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', '');

在上面,我有一个候选表和另一个候选表候选表,分别用于存储候选人详细信息和候选人分数。 candidate_subjects具有科目的候选人分数。注意数学的主题ID是2,英语Id是1.通过标记是40,这是ca_score + exam_score的总和。候选评论的条件是如果(数学是<40或英语是<40)评论的总分是“RESIT”#39;否则如果(math&gt; = 40和eng&gt; = 40)并且总科目通过&gt; = 6评论是&#39; PASS&#39;否则,如果(数学中的得分<40且得分为英镑<40)且总科目超过&lt; 6评论是&#39; FAIL&#39;否则如果(数学> 40和英国> 40)并且总科目通过&lt; 6评论是FAIL。

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

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

3 个答案:

答案 0 :(得分:0)

在哪里?对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**)

答案 1 :(得分:0)

使用简单的子查询。

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

答案 2 :(得分:0)

要根据您的条件更新候选人备注列,它可以是一个复杂的查询

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;

DEMO

SELECT *

SELECT ids

某些注意事项可确保您的架构中包含以下索引

  
      
  • candidate_subjects中的candidate_id应设置为候选表的外键引用,并应编入索引

  •   
  • 在(ca_score + exam_score)

  • 上添加综合索引   
  • 为subject_id添加索引

  •   

如果您仍然遇到长时间的执行问题,请运行批量查询,例如join(....)部分添加

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

LIMIT

相关问题