0

我正在尝试从 subject_inv 表中获取具有最佳匹配主题的学生列表。我的查询的问题是它需要更改 sql_mode。有没有办法在不更改 sql_mode 参数的情况下修改此查询。

    SELECT `student`.*, `subject_inv`.`subject_name`, `score`.`custom_score`, 
    MIN(
    CASE WHEN (`student`.`subject` = `subject_inv`.`subject_name`) THEN 1 WHEN (`student`.`topic1` = `subject_inv`.`subject_name`) THEN 2 WHEN (`student`.`topic2` = `subject_inv`.`subject_name`) THEN 3 WHEN (`student`.`topic3` = `subject_inv`.`subject_name`) THEN 4 END
    ) AS priority 
    FROM `student` 
LEFT OUTER JOIN `subject_inv` ON `subject_inv`.`subject_name`=`student`.`subject` OR `subject_inv`.`subject_name` = `student`.`topic1` OR `subject_inv`.`subject_name` = `student`.`topic2` OR `subject_inv`.`subject_name` = `student`.`topic3` 
LEFT OUTER JOIN `score` ON `student`.`id`=`score`.`id` GROUP BY `student`.`id`, priority

它给了我以下错误。当我将 sql_mode 从“only_full_group_by”更改为其他时,它可能应该修复。

#1055 - Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'mydb.student.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

有没有办法在不改变 sql_mode 的情况下得到这个结果?

student
id | full_name | subject | topic1 | topic2 | topic3
___________________________________________________
1  | tom       | sbj1    | sbj4   |        |
2  | sam       | sbj3    | sbj7   |        |
3  | ron       | sbj6    | sbj2   |        |    

subject_inv
id | subject_name | tutor
__________________________
1  | sbj1         | tut1
2  | sbj7         | tut2
3  | sbj4         | tut3
4  | sbj9         | tut3

score
id | custom_score
__________________
1  | 10         
2  | 6         
3  | 9         
4  | 4

预期成绩:::

id | full_name | subject | topic1 | topic2 | topic3 | subject_name | custom_score
________________________________________________________________________________
1  | tom       | sbj1    | sbj4   |        |        | sbj1         | 10
2  | sam       | sbj3    | sbj7   |        |        | sbj7         | 6
3  | ron       | sbj6    | sbj2   |        |        | NULL         | 9
4

2 回答 2

1

您可以将内部联接与 MIN 的子选择一起使用,例如:

 SELECT distinct  `student`.*, `subject_inv`.`subject_name`, `score`.`custom_score`
 , t.priority 
  FROM `student` 
  INNER JOIN (

    select  `student`.`id`, MIN(
        CASE  WHEN (`student`.`subject` = `subject_inv`.`subject_name`) THEN 1 
              WHEN (`student`.`topic1` = `subject_inv`.`subject_name`) THEN 2 
              WHEN (`student`.`topic2` = `subject_inv`.`subject_name`) THEN 3 
              WHEN (`student`.`topic3` = `subject_inv`.`subject_name`) THEN 4 END
        ) AS priority 
        FROM `student`
        LEFT OUTER JOIN `subject_inv` ON `subject_inv`.`subject_name`=`student`.`subject` 
            OR `subject_inv`.`subject_name` = `student`.`topic1` 
              OR `subject_inv`.`subject_name` = `student`.`topic2` 
                OR `subject_inv`.`subject_name` = `student`.`topic3`
    group by `student`.`id`
  ) t on t.`id` = `student`.`id`
  LEFT OUTER JOIN `subject_inv` ON `subject_inv`.`subject_name`=`student`.`subject` 
      OR `subject_inv`.`subject_name` = `student`.`topic1` 
        OR `subject_inv`.`subject_name` = `student`.`topic2` 
          OR `subject_inv`.`subject_name` = `student`.`topic3` 
  LEFT OUTER JOIN `score` ON `student`.`id`=`score`.`id` 

但是对于 sql_mode=only_full_group_by
如果您需要不在组中的 outhers 列,您也应该使用聚合函数

 SELECT  `student`.*
 , min(`subject_inv`.`subject_name`)
 , min(`score`.`custom_score`)
 , t.priority 
  FROM `student` 
  INNER JOIN (

    select  `student`.`id`, MIN(
        CASE  WHEN (`student`.`subject` = `subject_inv`.`subject_name`) THEN 1 
              WHEN (`student`.`topic1` = `subject_inv`.`subject_name`) THEN 2 
              WHEN (`student`.`topic2` = `subject_inv`.`subject_name`) THEN 3 
              WHEN (`student`.`topic3` = `subject_inv`.`subject_name`) THEN 4 END
        ) AS priority 
        FROM `student`
        LEFT OUTER JOIN `subject_inv` ON `subject_inv`.`subject_name`=`student`.`subject` 
            OR `subject_inv`.`subject_name` = `student`.`topic1` 
              OR `subject_inv`.`subject_name` = `student`.`topic2` 
                OR `subject_inv`.`subject_name` = `student`.`topic3`
    group by `student`.`id`
  ) t on t.`id` = `student`.`id`
  LEFT OUTER JOIN `subject_inv` ON `subject_inv`.`subject_name`=`student`.`subject` 
      OR `subject_inv`.`subject_name` = `student`.`topic1` 
        OR `subject_inv`.`subject_name` = `student`.`topic2` 
          OR `subject_inv`.`subject_name` = `student`.`topic3` 
  LEFT OUTER JOIN `score` ON `student`.`id`=`score`.`id` 
  GROUP BY `student`.`id`, t.priority  
于 2018-08-19T06:25:56.370 回答
1

我很想知道这个查询是如何执行的(以及它是否产生预期的结果),使用合并来确定优先级。注意我已经重命名了这些表。

drop table if exists st,su,sc;
create table st(id int, full_name varchar(20), subject varchar(20), topic1 varchar(20), topic2 varchar(20), topic3 varchar(20));
insert into st values
(1  , 'tom'       , 'sbj1'    , 'sbj4'   , null,null),
(2  , 'sam'       , 'sbj3'    , 'sbj7'   , null,null),       
(3  , 'ron'       , 'sbj6'    , 'sbj2'   , null,null);

create table su(id int, subject_name varchar(20), tutor varchar(20));
insert into su values
(1  , 'sbj1'         , 'tut1'),
(2  , 'sbj7'         , 'tut2'),
(3  , 'sbj4'         , 'tut3'),
(4  , 'sbj9'         , 'tut3');

create table sc(id int, custom_score int);
insert into sc values
(1  , 10),         
(2  , 6  ),       
(3  , 9  ),       
(4  , 4);

select  st.id,st.full_name,st.subject,st.topic1,st.topic2,st.topic3,
        coalesce((select su.subject_name from su where su.subject_name = st.subject) ,
                (select su.subject_name from su where su.subject_name = st.topic1) ,
                (select su.subject_name from su where su.subject_name = st.topic2) ,
                (select su.subject_name from su where su.subject_name = st.topic3)
                )  subjectname,
         custom_score
from st
left join sc on sc.id = st.id;

+------+-----------+---------+--------+--------+--------+-------------+--------------+
| id   | full_name | subject | topic1 | topic2 | topic3 | subjectname | custom_score |
+------+-----------+---------+--------+--------+--------+-------------+--------------+
|    1 | tom       | sbj1    | sbj4   | NULL   | NULL   | sbj1        |           10 |
|    2 | sam       | sbj3    | sbj7   | NULL   | NULL   | sbj7        |            6 |
|    3 | ron       | sbj6    | sbj2   | NULL   | NULL   | NULL        |            9 |
+------+-----------+---------+--------+--------+--------+-------------+--------------+
3 rows in set (0.02 sec)
于 2018-08-19T09:54:19.290 回答