I have to create a report on some student completions. The students each belong to one client. Here are the tables (simplified for this question).
CREATE TABLE `clients` (
`clientId` int(10) unsigned NOT NULL auto_increment,
`clientName` varchar(100) NOT NULL default '',
`courseNames` varchar(255) NOT NULL default ''
)
The courseNames
field holds a comma-delimited string of course names, eg "AB01,AB02,AB03"
CREATE TABLE `clientenrols` (
`clientEnrolId` int(10) unsigned NOT NULL auto_increment,
`studentId` int(10) unsigned NOT NULL default '0',
`courseId` tinyint(3) unsigned NOT NULL default '0'
)
The courseId
field here is the index of the course name in the clients.courseNames field. So, if the client's courseNames
are "AB01,AB02,AB03", and the courseId
of the enrolment is 2
, then the student is in AB03.
Is there a way that I can do a single select on these tables that includes the course name? Keep in mind that there will be students from different clients (and hence have different course names, not all of which are sequential,eg: "NW01,NW03")
Basically, if I could split that field and return a single element from the resulting array, that would be what I'm looking for. Here's what I mean in magical pseudocode:
SELECT e.`studentId`, SPLIT(",", c.`courseNames`)[e.`courseId`]
FROM ...
Seeing that it's a fairly popular question - the answer is YES.
For a column
column
in tabletable
containing all of your coma separated values:Please remember however to not store CSV in your DB
Per @Mark Amery - as this translates coma separated values into an
INSERT
statement, be careful when running it on unsanitised dataJust to reiterate, please don't store CSV in your DB; this function is meant to translate CSV into sensible DB structure and not to be used anywhere in your code. If you have to use it in production, please rethink your DB structure
Here's what I've got so far (found it on the page Ben Alpert mentioned):
Until now, I wanted to keep those comma separated lists in my SQL db - well aware of all warnings!
I kept thinking that they have benefits over lookup tables (which provide a way to a normalized data base). After some days of refusing, I've seen the light:
In short, there is a reason why there is no native SPLIT() function in MySQL.
There's an easier way, have a link table, i.e.:
Table 1: clients, client info, blah blah blah
Table 2: courses, course info, blah blah
Table 3: clientid, courseid
Then do a JOIN and you're off to the races.
I've resolved this kind of problem with a regular expression pattern. They tend to be slower than regular queries but it's an easy way to retrieve data in a comma-delimited query column
the greedy question mark helps to search at the beggining or the end of the string.
Hope that helps for anyone in the future