sql group_concat 并在其中得到相反的结果

sql group_concat and where in get inverted results

我很难查询。

如果我 运行 这个(仅限第一个双学期):

SELECT subject.name as subject, GROUP_CONCAT(evaluations_mark.note) as mark 
FROM evaluations_mark 
LEFT JOIN subject ON evaluations_mark.subject_id = subject.subject_id
LEFT JOIN user ON evaluations_mark.user_id = user.user_id
WHERE evaluations_mark.number_exam = 1 AND evaluations_mark.user_id = 28265
AND subject.print_visible='1' 
AND subject.number_exam = '4' 
GROUP BY evaluations_mark.subject_id

我得到的结果很好:

+--------------------+-----+
| Lengua             | SA  |
| Matematica         | SA  |
| Ciencias Sociales  | MSA |
| Ciencias Naturales | MSA |
| Italiano           | MSA |
| Ingles             | SA  |<--RIGHT!
+--------------------+-----+

如果我 运行 这个其他查询:

SELECT subject.name as subject, GROUP_CONCAT(evaluations_mark.note) as mark 
FROM evaluations_mark 
LEFT JOIN subject ON evaluations_mark.subject_id = subject.subject_id
LEFT JOIN user ON evaluations_mark.user_id = user.user_id
WHERE evaluations_mark.number_exam = 2 AND evaluations_mark.user_id = 28265
AND subject.print_visible='1' 
AND subject.number_exam = '4' 
GROUP BY evaluations_mark.subject_id

我得到这个结果也很好(仅限第二个双学期):

+--------------------+-----+
| Lengua             | SA  |
| Matematica         | SA  |
| Ciencias Sociales  | SA  |
| Ciencias Naturales | MSA |
| Italiano           | MSA |
| Ingles             | MSA |<--RIGHT!
+--------------------+-----+

现在,问题终于来了。如果我 运行 这个该死的查询:

SELECT subject.name as subject, GROUP_CONCAT(evaluations_mark.note) as mark 
FROM evaluations_mark 
LEFT JOIN subject ON evaluations_mark.subject_id = subject.subject_id
LEFT JOIN user ON evaluations_mark.user_id = user.user_id
WHERE evaluations_mark.number_exam IN (1,2) AND evaluations_mark.user_id = 28265
AND subject.print_visible='1' 
AND subject.number_exam = '4' 
GROUP BY evaluations_mark.subject_id

我得到了 1 个倒置的记录(两个双学期):

+--------------------+-----+-----+
| Lengua             | SA  | SA  |
| Matematica         | SA  | SA  |
| Ciencias Sociales  | MSA | SA  |
| Ciencias Naturales | MSA | MSA |
| Italiano           | MSA | MSA |
| Ingles             | MSA | SA  |******* <<--WRONG! IT'S INVERTED!
+--------------------+-----+-----+

第 1 列:科目 第二列:第一个双学期(第一个结果) 第 3 列:第二个双学期(第二个结果)

到底为什么会这样?提前致谢!

EDIT2:用文字替换了 3 张图片。

EDIT3:这里是 table 结构

TABLE `evaluations_mark` (
  `mark_id` int(13) NOT NULL,
  `note` varchar(225) NOT NULL,
  `comments` text NOT NULL,
  `subject_id` int(13) NOT NULL,
  `course_id` int(13) NOT NULL,
  `user_id` int(13) NOT NULL,
  `evaluation_id` int(13) NOT NULL,
  `number_exam` int(2) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

TABLE `subject` (
  `subject_id` int(6) NOT NULL,
  `name` varchar(50) NOT NULL,
  `course_id` int(6) NOT NULL,
  `teacher_id` int(6) NOT NULL,
  `load_type` varchar(20) NOT NULL,
  `hours` int(11) NOT NULL,
  `area_id` int(2) NOT NULL,
  `active` tinyint(1) NOT NULL,
  `number_exam` int(6) NOT NULL,
  `parent` int(5) NOT NULL,
  `print_visible` tinyint(1) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

编辑 4:从 tables

添加了所需的内容

evaluations_mark table:

mark_id     note    comments    subject_id  course_id   1   user_id     evaluation_id   number_exam     
4363    SA      87  8   28265   0   1   
4892    MSA     84  8   28265   0   2   
1078    SA      85  8   28265   0   1   
3646    MSA     88  8   28265   0   1   
2634    MSA     89  8   28265   0   1   
125 SA      80  8   28265   0   1   
147 MSA     82  8   28265   0   1   
1430    MSA     84  8   28265   0   1   
169 MSA     83  8   28265   0   1   
3753    SA      80  8   28265   0   2   
3510    MSA     85  8   28265   0   2   
191 SA      81  8   28265   0   1   
3775    SA      81  8   28265   0   2   
6858    MSA     86  8   28265   0   1   
3279    MSA     83  8   28265   0   2   
3797    SA      82  8   28265   0   2   

主题table:

subject_id  name    course_id   teacher_id  load_type   hours   area_id     active  number_exam     parent  print_visible   
80  Lengua y Literatura 8   0   1   4   2   0   4   0   1   
81  Matemática  8   0   1   4   2   0   4   0   1   
82  Ciencias Sociales   8   0   1   4   2   0   4   0   1   
83  Ciencias Naturales  8   0   1   4   2   0   4   0   1   
84  Italiano    8   0   2   5   2   0   4   0   1   
85  Inglés  8   0   2   4   2   0   4   0   1   
86  Expresion Plástica  8   0   2   3   2   0   2   0   1   
87  Música  8   0   2   2   2   0   2   0   1   
88  Informática 8   0   2   3   2   0   2   0   1   
89  Educación Física    8   0   2   2   2   0   2   0   1   

编辑 4:我标记了正确和错误。

在我看来,LEFT JOINuser 在此查询中是多余的,因为没有以任何方式引用 table 中的任何列。您可以将查询简化为

SELECT subject.name as subject, GROUP_CONCAT(evaluations_mark.note) as mark 
FROM evaluations_mark 
LEFT JOIN subject ON evaluations_mark.subject_id = subject.subject_id
WHERE evaluations_mark.number_exam IN (1,2) AND evaluations_mark.user_id = 28265
AND subject.print_visible='1' 
AND subject.number_exam = '4' 
GROUP BY evaluations_mark.subject_id

此外,您的结果绝对应该包含只有两列subjectmark。在第二列中,您会发现多个结果(字母组)作为逗号分隔列表。

我根据您的信息创建了一个小演示 http://rextester.com/DXAQIP21690(实际测试数据仍然缺失!)来说明我的观点,即输出仅包含两个列。也许您可以进一步指导我们您的问题所在?

编辑1
我添加了您提供的示例数据:http://rextester.com/OVSL70192 欢迎试用演示。

请告诉我们:您的期望输出是什么? “结果反转”是什么意思?我跟不上你了

编辑2
好的,您对“错误”的评论进一步澄清了您的问题。 在我最新版本的演示 http://rextester.com/XWSO90046 中,您现在会发现 两个输出列 mark1mark2:

SELECT s.name as subject, 
  group_concat(CASE e.number_exam WHEN 1 THEN e.note END)  as mark1,
  group_concat(CASE e.number_exam WHEN 2 THEN e.note END)  as mark2 
FROM evaluations_mark e 
LEFT JOIN subject s ON e.subject_id = s.subject_id
WHERE e.number_exam IN (1,2) AND e.user_id = 28265
  AND s.print_visible='1'    AND s.number_exam = '4' 
GROUP BY e.subject_id

结果:

subject              mark1   mark2
Lengua y Literatura  SA      SA
Matemática           SA      SA
Ciencias Sociales    MSA     SA
Ciencias Naturales   MSA     MSA
Italiano             MSA     MSA
Inglés               SA      MSA

原始查询中的 group_concat 函数没有指定任何 order by 子句,因此未定义内部元素的顺序(即任意!)。您可以通过在 GROUP_CONCAT 子句中使用 ORDER BY 来改善这种情况,如下所示:

--- 顺便说一句,这是适用于 OP 的代码(见下面的评论)---

OP 接受的代码:

SELECT s.name as subject, 
  GROUP_CONCAT(e.note ORDER BY e.number_exam) as mark 
FROM evaluations_mark e
LEFT JOIN subject s ON e.subject_id = s.subject_id
WHERE e.number_exam IN (1,2) AND e.user_id = 28265
AND s.print_visible='1' 
AND s.number_exam = '4' 
GROUP BY e.subject_id

这会让你

subject              mark
-----------------------------
Lengua y Literatura  SA,SA
Matemática           SA,SA
Ciencias Sociales    MSA,SA
Ciencias Naturales   MSA,MSA
Italiano             MSA,MSA
Inglés               SA,MSA

参见此处:http://rextester.com/UEZ55062,但请注意 mark 仍然只是 一列

编辑3
刚刚也在 phpmyadmin 中测试了它:

select version()
>> 5.1.73-1+deb6u1-log

我还在这个 public 沙箱上测试了它:https://demo.phpmyadmin.net/STABLE/db_structure.php?server=2&db=Test 并且有效!使用 root 和空(=no!)密码登录。

上面“OP 接受的代码”下显示的代码再次产生了这个结果:

编辑4
最后一点:严格来说,您还应该在查询中使用 MAX(s.name) as subject, ...,因为您仅按 e.subject_id 进行分组。 MySql 在这方面相当(太)宽容了。