我正在构建一个应用程序,该应用程序将列出学生的考试相关详细信息。
CREATE TABLE IF NOT EXISTS `es_student` (
`student_id` int(11) NOT NULL,
`fname` varchar(50) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=42 DEFAULT CHARSET=latin1;
INSERT INTO `es_student` (`student_id`, `fname`) VALUES
(1,'John');
有多个科目
CREATE TABLE IF NOT EXISTS `es_subject` (
`subject_id` int(11) NOT NULL,
`subject` varchar(50) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=42 DEFAULT CHARSET=latin1;
INSERT INTO `es_subject` (`subject_id`, `subject`) VALUES
(1,'Math'),
(2,'English'),
(3,'Science'),
(4,'Physics');
有多个考试。但并非所有考试都是针对某一主题进行的。 例如:对于数学,所有三门考试都已进行,但对于英语,只进行了一次考试。因此,我希望将零作为未完成的考试(对于某个科目)的分数。
CREATE TABLE IF NOT EXISTS `es_exam` (
`exam_id` int(11) NOT NULL,
`exam` varchar(50) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=42 DEFAULT CHARSET=latin1;
INSERT INTO `es_exam` (`exam_id`, `exam`) VALUES
(1,'Exam 1'),
(2,'Exam 2'),
(3,'Exam 3');
这是我存储所有标记的方式
CREATE TABLE IF NOT EXISTS `es_mark` (
`mark_id` int(11) NOT NULL,
`exam_id` int(11) NOT NULL,
`subject_id` int(11) NOT NULL,
`student_id` int(11) NOT NULL,
`mark` int(11) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=42 DEFAULT CHARSET=latin1;
INSERT INTO `es_mark` (`mark_id`, `exam_id`,`subject_id`, `student_id`,`mark`) VALUES
(1,1,1,1,11),
(2,2,1,1,15),
(3,3,1,1,12),
(4,3,2,1,11),
(5,1,3,1,1),
(6,3,3,1,2),
(7,2,4,1,3);
但是我写的查询对那些尚未进行的考试没有显示为零。
SELECT es_mark.mark_id,es_mark.mark,es_exam.exam ,es_subject.subject,es_subject.subject_id,es_student.fname
FROM es_mark
LEFT JOIN es_subject ON es_mark.subject_id=es_subject.subject_id
LEFT JOIN es_student ON es_mark.student_id=es_student.student_id
LEFT JOIN es_exam ON es_exam.exam_id=es_mark.exam_id
WHERE es_mark.student_id=1
GROUP BY es_mark.mark_id
这是我得到的结果:
mark_id mark exam subject subject_id fname
1 11 Exam 1 Math 1 John
2 15 Exam 2 Math 1 John
3 12 Exam 3 Math 1 John
4 11 Exam 3 English 2 John
5 1 Exam 1 Science 3 John
6 2 Exam 3 Science 3 John
7 3 Exam 2 Physics 4 John
这就是我想要实现的目标:
mark_id mark exam subject subject_id fname
1 11 Exam 1 Math 1 John
2 15 Exam 2 Math 1 John
3 12 Exam 3 Math 1 John
4 11 Exam 3 English 2 John
0 0 Exam 2 English 2 John
0 0 Exam 1 English 2 John
依旧......
是否有可能为那些尚未进行的考试插入零作为标记?
P.S:mark_id无关紧要。我知道它不能重复,因为它是一个主键字段,我也把0放在所需的输出中。
答案 0 :(得分:1)
你应该尝试这个查询,这个技巧是在带有两个交叉连接的deliverd表中。 这些交叉连接使用表es_subject,es_exam和es_student中的数据生成4 * 3 * 1 = 12条记录,以便在这三个表之间进行所有可能的组合。
请注意,你不能得到你试图达到的顺序,这就是为什么我的结果不同但是mark_id和mark是零,没有匹配。
SELECT
IF (es_mark.mark_id IS NULL, 0, es_mark.mark_id) AS mark_id
, IF (es_mark.mark IS NULL, 0, es_mark.mark) AS mark
, all_exam.exam
, all_exam.subject
, all_exam.subject_id
, all_exam.fname
FROM (
SELECT
*
FROM
es_subject
CROSS JOIN
es_exam
CROSS JOIN
es_student
)
AS
all_exam
LEFT JOIN
es_mark
ON
all_exam.exam_id = es_mark.exam_id
AND
all_exam.subject_id = es_mark.subject_id
LEFT JOIN
es_subject
ON
es_mark.subject_id = es_subject.subject_id
LEFT JOIN
es_student
ON
es_mark.student_id = es_student.student_id
LEFT JOIN
es_exam
ON
es_exam.exam_id = es_mark.exam_id
ORDER BY
all_exam.subject_id ASC
, all_exam.exam ASC
结果
mark_id mark exam subject subject_id fname
------- ------ ------ ------- ---------- --------
1 11 Exam 1 Math 1 John
2 15 Exam 2 Math 1 John
3 12 Exam 3 Math 1 John
0 0 Exam 1 English 2 John
0 0 Exam 2 English 2 John
4 11 Exam 3 English 2 John
5 1 Exam 1 Science 3 John
0 0 Exam 2 Science 3 John
6 2 Exam 3 Science 3 John
0 0 Exam 1 Physics 4 John
7 3 Exam 2 Physics 4 John
0 0 Exam 3 Physics 4 John
答案 1 :(得分:0)
node.allKnobs()
答案 2 :(得分:0)
使用时必须使用DEFAULT值。 如果未指定其他值,则默认值将添加到所有新记录中。
答案 3 :(得分:0)
您需要将mark
调整为以下内容:
`mark` int(11) DEFAULT 0 NOT NULL
根据您的示例显示,它正在将数据拉入mark
字段并添加1,2&因此,由于提供了数据,所以它并没有默认为0。
对于INSERT查询,即使您声明具有DEFAULT值的列,它们也必须填充所有字段,因为它不会允许空数据字段。对于填充和未填充mark
数据的查询,您需要具有单独的INSERT INTO查询。以下示例 -
INSERT INTO `es_mark` (`mark_id`, `exam_id`,`subject_id`, `student_id`,`mark`) VALUES
(1,1,1,1,11),
(2,2,1,1,15),
(3,3,1,1,12),
(4,3,2,1,11);
INSERT INTO `es_mark` (`mark_id`, `exam_id`,`subject_id`, `student_id`)
VALUES
(5,2,2,1),
(6,1,2,1);
希望这有助于您走上正确的道路,了解您希望通过项目实现的目标。