我正在尝试从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
答案 0 :(得分: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
如果您需要外部列,那么您也应该使用聚集功能
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
答案 1 :(得分: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)