问题
Given a complex query for a beginner in database, how can I convert this access sql to mysql? Here is the MS ACCESS query:
SELECT tblSections.[Course Code], tblSections.Section, tblSections.Day, tblSections.[Start Time], tblSections.[End Time], tblSections.Room, tblProfessors.[Last Name], tblProfessors.[First Name], Count(tblStudentsCoursesSections.[Student ID]) AS Enrolled, ([tblCourses].[Max])-[Enrolled] AS Slots
FROM tblCourses INNER JOIN (tblStudentsCoursesSections RIGHT JOIN (tblProfessors INNER JOIN tblSections ON tblProfessors.[ID Number] = tblSections.[Professor ID]) ON (tblStudentsCoursesSections.[Course Code] = tblSections.[Course Code]) AND (tblStudentsCoursesSections.Section = tblSections.Section)) ON tblCourses.[Course Code] = tblSections.[Course Code]
GROUP BY tblSections.[Course Code], tblSections.Section, tblSections.Day, tblSections.[Start Time], tblSections.[End Time], tblSections.Room, tblProfessors.[Last Name], tblProfessors.[First Name], tblStudentsCoursesSections.[Course Code], tblStudentsCoursesSections.Section, tblCourses.Max
HAVING (((tblSections.[Course Code])="SOCTEC2"));

I tried converting it by replacing [] by `` but it didn't work. Is there something wrong? This is what I inputted in the mySQL in the command line. The corresponding error is also displayed.
SELECT tblSections.`Course Code`, tblSections.Section, tblSections.Day, tblSections.`Start Time`, tblSections.`End Time`, tblSections.Room, tblProfessors.`Last Name`, tblProfessors.`First Name`, Count(tblStudentsCoursesSections.`Student ID`) AS Enrolled, (`tblCourses`.`Max`)-`Enrolled` AS Slots FROM tblCourses INNER JOIN (tblStudentsCoursesSections RIGHT JOIN (tblProfessors INNER JOIN tblSections ON tblProfessors.`ID Number` = tblSections.`Professor ID`) ON (tblStudentsCoursesSections.Section = tblSections.Section) AND (tblStudentsCoursesSections.`Course Code` = tblSections.`Course Code`)) ON tblCourses.`Course Code` = tblSections.`Course Code` GROUP BY tblSections.`Course Code`, tblSections.Section, tblSections.Day, tblSections.`Start Time`, tblSections.`End Time`, tblSections.Room, tblProfessors.`Last Name`, tblProfessors.`First Name`, tblStudentsCoursesSections.`Course Code`, tblStudentsCoursesSections.Section, tblCourses.Max HAVING (((tblSections.`Course Code`)="SOCTEC2"));
Isn't it that the count of the enrolled student will be displayed along the enrolled field?

UPDATE!!
I did what you suggested but I reverted back to HAVING keyword since WHERE results to syntax error.
SELECT
tblSections.`Course Code`,
tblSections.`Section`,
tblSections.`Day`,
tblSections.`Start Time`,
tblSections.`End Time`,
tblSections.`Room`,
tblProfessors.`Last Name`,
tblProfessors.`First Name`,
COUNT(tblStudentsCoursesSections.`Student ID`) AS `Enrolled`,
/* Since Enrolled was just defined as an alias in this scope you cannot use it
in the SELECT yet, but you can do the aggregate COUNT again */
(`tblCourses`.`Max` - COUNT(tblStudentsCoursesSections.`Student ID`)) AS `Slots`
FROM
# Order your table joins according to the pairs used in ON clauses...
tblCourses
INNER JOIN tblSections ON tblCourses.`Course Code` = tblSections.`Course Code`
RIGHT JOIN tblProfessors ON tblProfessors.`ID Number` = tblSections.`Professor ID`
INNER JOIN tblStudentsCoursesSections
ON ((tblStudentsCoursesSections.Section = tblSections.Section)
AND (tblStudentsCoursesSections.`Course Code` = tblSections.`Course Code`))
GROUP BY
tblSections.`Course Code`,
tblSections.`Section`,
tblSections.`Day`,
tblSections.`Start Time`,
tblSections.`End Time`,
tblSections.`Room`,
tblProfessors.`Last Name`,
tblProfessors.`First Name`,
/* These are not in your SELECT list and so should probably not be in the GROUP BY
tblStudentsCoursesSections.`Course Code`,
tblStudentsCoursesSections.`Section`,
Might need to group on `Slots` instead of tblCourses.Max */
tblCourses.Max
/* This should be a WHERE rather than HAVING since it does not operate on an aggregate */
HAVING
/* Single quotes preferred for string literals */
tblSections.`Course Code` = 'SOCTEC2';
Unfortunately, sections with zero enrolled student does not show up. Why is that so?

回答1:
MS Access has an unusual requirement that JOIN
s be enclosed in a messy set of nested ()
. What you need to do here is unravel which tables are joined in pairs by inspecting the various ON
conditions then lining them up appropriately
I've also enclosed the rest of your columns and aliases in backticks inside the GROUP BY
where you had some missing.
SELECT
tblSections.`Course Code`,
tblSections.`Section`,
tblSections.`Day`,
tblSections.`Start Time`,
tblSections.`End Time`,
tblSections.`Room`,
tblProfessors.`Last Name`,
tblProfessors.`First Name`,
COUNT(tblStudentsCoursesSections.`Student ID`) AS `Enrolled`,
/* Since Enrolled was just defined as an alias in this scope you cannot use it
in the SELECT yet, but you can do the aggregate COUNT again */
(`tblCourses`.`Max` - COUNT(tblStudentsCoursesSections.`Student ID`)) AS `Slots`
FROM
# Order your table joins according to the pairs used in ON clauses...
tblCourses
INNER JOIN tblSections ON tblCourses.`Course Code` = tblSections.`Course Code`
/* This RIGHT JOIN is assumed to be returning all records from tblProfessors regardless
of match in tblSections. If that is the opposite of what was intended, change to LEFT JOIN */
RIGHT JOIN tblProfessors ON tblProfessors.`ID Number` = tblSections.`Professor ID`
INNER JOIN tblStudentsCoursesSections
ON (tblStudentsCoursesSections.Section = tblSections.Section)
AND (tblStudentsCoursesSections.`Course Code` = tblSections.`Course Code`)
/* This should be a WHERE rather than HAVING since it does not operate on an aggregate */
WHERE
/* Single quotes preferred for string literals */
tblSections.`Course Code` = 'SOCTEC2';
GROUP BY
tblSections.`Course Code`,
tblSections.`Section`,
tblSections.`Day`,
tblSections.`Start Time`,
tblSections.`End Time`,
tblSections.`Room`,
tblProfessors.`Last Name`,
tblProfessors.`First Name`,
/* These are not in your SELECT list and so should probably not be in the GROUP BY
tblStudentsCoursesSections.`Course Code`,
tblStudentsCoursesSections.`Section`,
Might need to group on `Slots` instead of tblCourses.Max */
`Slots`
Addendum
Unfortunately, sections with zero enrolled student does not show up. Why is that so?
Since you have an INNER JOIN
between tblStudentsCoursesSections
and tblSections
, no records in tblStudentsCoursesSections
will eliminate that section from the results. To ensure the section is returned anyway, use a LEFT JOIN tblStudentsCoursesSections
in place of INNER JOIN tblStudentsCoursesSections
. Since tblSections
is on the "left side" of the join, it will return even if there's no match.
来源:https://stackoverflow.com/questions/20661805/how-do-i-convert-this-access-query-to-mysql-query