【问题标题】:sql group_concat and where in get inverted resultssql group_concat 和在哪里得到倒置的结果
【发布时间】:2018-08-07 12:59:00
【问题描述】:

我很难查询。

如果我运行这个(仅限第一胎):

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 条记录倒置(两个 bimester):

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

第一栏:主题 第 2 栏:第 1 次妊娠(第一个结果) 第 3 列:第 2 次孕期(第二个结果)

到底为什么会发生这种情况?提前致谢!

EDIT2:将 3 张图片替换为文字。

EDIT3:这里是表结构

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:从两个表中添加所需的内容

evaluations_mark 表:

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   

主题表:

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:我标记了正确和错误。

【问题讨论】:

  • 当您像这样将右侧表条件放在 WHERE 子句中时,那些 LEFT JOINS 会返回常规的 INNER JOIN 结果。将条件移至 ON 子句以获得真正的 LEFT JOIN 结果。
  • 对不起..没有关注你..怎么样?可以举个例子吗?
  • 第一张图1和2是一样的。第二,你说的倒置是什么意思?向我们展示您期望的结果。第三张图片没有说明问题是什么,因为还有另一行具有相同的值,你不称它为倒置
  • 将表格和数据发布为文本READ THIS
  • 向我们展示数据库架构、示例数据、当前和预期输出。请阅读How-to-Ask 这里是START 了解如何提高问题质量并获得更好答案的好地方。 How to create a Minimal, Complete, and Verifiable example 尝试在rextester.com 中创建样本

标签: sql where group-concat


【解决方案1】:

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

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
好的,您关于“错误”的 cmets 进一步澄清了您的问题。 在我最新版本的演示 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 的代码(参见下面的 cmets)---

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

我还在这个公共沙盒上测试了它: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 在这方面相当(太)宽容。

【讨论】:

  • 看起来是多余的,但结果还是不对。
  • 感谢您的回答。我需要将其标记为一列,因为稍后我需要用逗号将结果用于 php 中的数组,所以我需要放弃你的第一个选项(我在 phpmyadmin/mysql 中测试过它并且它有效!)。至于您的第二个选项,尝试按照建议使用 order by,但问题仍然存在于 phpmyadmin/mysql 中。但不在 sqlfiddle 和 rextester.com 中。所以我该怎么做? mariadb/mysql 中的错误?
  • 感谢您的反馈。是的,它在 mysql 中有效,但在 mariadb 中无效。那里似乎有一个错误。我已经报告了一个错误。
  • 确实在 MariaDB 中工作,请参见此处:dbfiddle.uk/…
  • 天哪!这个就像一个魅力......但我不明白其中的区别!选择 s.name 作为主题,GROUP_CONCAT(e.note ORDER BY e.number_exam) 作为 mark FROM evaluations_mark e LEFT JOIN subject s ON e.subject_id = s.subject_id WHERE e.number_exam IN ($numberSql) AND e.user_id = ' $user_id' AND s.print_visible='1' AND s.number_exam = '4' GROUP BY e.subject_id";
猜你喜欢
  • 2019-12-21
  • 2011-07-02
  • 2010-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-27
相关资源
最近更新 更多