我向高中生教授网页设计。最近,我向他们介绍了使用SQL和Coldfusion进行动态Web设计的方法。我一直在保持它很简单,但是我确实想向他们展示一个复杂的SQL语句和一个复杂的cfoutput。不幸的是,我使问题变得过于复杂,无法解决!这是我的数据库结构的照片:
我正在尝试输出每个班级的注册学生名单以及该班级提供的课程以及讲课的老师。这是我要输出的示例
机器人技术
第一节
史密斯先生
然后我要输出下一课的信息,依此类推。
这是我正在使用的cfoutput代码:
<cfoutput query="getRoster" group="staff">
#firstname# #lastname#<br>
#className#<br>
#sessionNumber#<br>
#title# #lastname#<br>
<cfoutput>
`<ol><li>#lastname#, #firstname#</li></ol>`
</cfoutput>
</cfoutput>
答案 0 :(得分:2)
假设您的查询已经返回了正确的数据,那么您将关闭。该查询只需要进行一些更改:
由于多个表中存在“ firstName”和“ lastName”列,因此查询必须对每个表应用不同的列alias,即SELECT student.lastName AS StudentLastName, ....
。否则,CF在看到#firstName#
和#lastName#
时将不知道要输出哪个值。
cfoutput可能应该按className
“分组”,而不是staff
。否则,如果将同一职员分配给多个班级,则不会显示所有班级名称。
CFOutput“组”要求对查询结果进行排序。确保查询是className
的ORDER(ed)BY(或您要分组的任何列),否则cfoutput将无法正确显示。
为了生成列表编号,<ol>
元素属于内部<cfoutput>
循环之外。
查询:
SELECT
c.className
, c.sessionNumber
, s.LastName AS StaffLastName
, s.FirstName AS StaffFirstName
, st.LastName AS StudentLastName
, st.FirstName AS StudentFirstName
FROM class c
INNER JOIN staff s ON s.id = c.staff
INNER JOIN studentOld st ON st.class1 = c.id
OR st.class2 = c.id
OR st.class3 = c.id
OR st.class4 = c.id
ORDER BY c.className, st.LastName, st.FirstName
CF
<cfoutput query="getRoster" group="className">
#StaffTitle# #StaffLastName# #StaffLastName#<br>
#className#<br>
#sessionNumber#<br>
<ol>
<cfoutput>
<li>#StudentLastName#, #StudentFirstName#</li>
</cfoutput>
</ol>
</cfoutput>
也就是说,如果可能的话,我将重组学生表,因为这不是表示student
和class
之间存在的many-to-many关系的典型方式。 (现在最好是加强良好的数据库结构习惯!)一种更干净,更规范的方法是从学生表中删除classX
列。然后将这些关系存储在单独的表中-作为单独的行-而不是列。这样就可以根据需要灵活地进行任意数量的注册。
CREATE TABLE student (
id int
, lastName varchar(100)
, firstName varchar(50)
)
-- stores each combination of student + class as a separate row
CREATE TABLE studentClass (
student int
, class int
)
然后,您就可以摆脱所有OR
语句,并使用更简洁的JOIN来检索课程和已注册的学生:
SELECT ...
FROM class c
INNER JOIN staff s ON s.id = c.staff
INNER JOIN studentClass sc ON sc.class = c.id
INNER JOIN student st ON st.id = sc.student
ORDER BY ....