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 JOIN
到 user
在此查询中是多余的,因为没有以任何方式引用 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
此外,您的结果绝对应该包含只有两列:subject
和mark
。在第二列中,您会发现多个结果(字母组)作为逗号分隔列表。
我根据您的信息创建了一个小演示 http://rextester.com/DXAQIP21690(实际测试数据仍然缺失!)来说明我的观点,即输出仅包含两个列。也许您可以进一步指导我们您的问题所在?
编辑1
我添加了您提供的示例数据:http://rextester.com/OVSL70192 欢迎试用演示。
请告诉我们:您的期望输出是什么? “结果反转”是什么意思?我跟不上你了
编辑2
好的,您对“错误”的评论进一步澄清了您的问题。
在我最新版本的演示 http://rextester.com/XWSO90046 中,您现在会发现 两个输出列 :mark1
和 mark2
:
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 在这方面相当(太)宽容了。
我很难查询。
如果我 运行 这个(仅限第一个双学期):
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 JOIN
到 user
在此查询中是多余的,因为没有以任何方式引用 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
此外,您的结果绝对应该包含只有两列:subject
和mark
。在第二列中,您会发现多个结果(字母组)作为逗号分隔列表。
我根据您的信息创建了一个小演示 http://rextester.com/DXAQIP21690(实际测试数据仍然缺失!)来说明我的观点,即输出仅包含两个列。也许您可以进一步指导我们您的问题所在?
编辑1
我添加了您提供的示例数据:http://rextester.com/OVSL70192 欢迎试用演示。
请告诉我们:您的期望输出是什么? “结果反转”是什么意思?我跟不上你了
编辑2
好的,您对“错误”的评论进一步澄清了您的问题。
在我最新版本的演示 http://rextester.com/XWSO90046 中,您现在会发现 两个输出列 :mark1
和 mark2
:
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 在这方面相当(太)宽容了。