ISSUE
I'm working on a content management system for a school, and I'd like to be able to create a view of multiple joined tables. In addition to joining the tables, I need to perform a PIVOT or GROUP_CONCAT (or some other function) in order to take multiple rows from each table and use them as columns in the view. To help visualize, here is a simplification of what I'm working with:
SETUP
STRUCTURE:
DROP TABLE IF EXISTS `date`;
CREATE TABLE `date` (
`col_pkid` int(11) NOT NULL AUTO_INCREMENT,
`col_guid` varchar(100) NOT NULL DEFAULT '',
`col_entry` varchar(100) NOT NULL,
`col_inquiry_name` varchar(100) NOT NULL,
`col_value` int(11) DEFAULT NULL,
PRIMARY KEY (`col_pkid`)
);
DROP TABLE IF EXISTS `bigText`;
CREATE TABLE `bigText` (
`col_pkid` int(11) NOT NULL AUTO_INCREMENT,
`col_guid` varchar(100) NOT NULL DEFAULT '',
`col_entry` varchar(100) NOT NULL,
`col_inquiry_name` varchar(100) NOT NULL,
`col_value` text,
PRIMARY KEY (`col_pkid`)
);
DROP TABLE IF EXISTS `smallText`;
CREATE TABLE `smallText` (
`col_pkid` int(11) NOT NULL AUTO_INCREMENT,
`col_guid` varchar(100) NOT NULL,
`col_entry` varchar(100) NOT NULL,
`col_inquiry_name` varchar(100) NOT NULL,
`col_value` varchar(100) DEFAULT '',
PRIMARY KEY (`col_pkid`)
);
DATA:
INSERT INTO `date` (`col_pkid`, `col_guid`, `col_entry`, `col_inquiry_name`, `col_value`)
VALUES
(1,'d2kih1ho5z','1','Semester',1294834220),
(2,'d2kih1j99y','2','Semester',1327077210);
INSERT INTO `bigText` (`col_pkid`, `col_guid`, `col_entry`, `col_inquiry_name`, `col_value`)
VALUES
(16,'d2kih1kxwh','1','Description','Lorem ipsum dolor sit amet...'),
(17,'d2kih1mhnn','2','Description','Consectetur adipiscing elit...');
INSERT INTO `smallText` (`col_pkid`, `col_guid`, `col_entry`, `col_inquiry_name`, `col_value`)
VALUES
(1,'d2kih1njuj','1','Title','Addition and Subtraction'),
(2,'d2kih1ot0x','1','Course','Math'),
(16,'d2kj5osy71','1','Location','Building 7'),
(17,'d2kj5p0z8f','1','Teachers','John'),
(18,'d2kj5p5efi','1','Teachers','Jane'),
(19,'d2kj5p98xv','1','Teachers',''),
(20,'d2kj5pasi9','1','Teachers',''),
(21,'d2kj5pbqbg','1','Teachers',''),
(22,'d2kj5pdxdb','2','Title','Reading Mark Twain'),
(23,'d2kih198do','2','Course','Literature'),
(24,'d2kj5opcgo','2','Location','Building 4'),
(25,'d2hd00n5eb','2','Teachers','Billy'),
(26,'d2hea3jo74','2','Teachers','Bob'),
(27,'d2hec78m5e','2','Teachers',''),
(28,'d2hec7bnar','2','Teachers',''),
(29,'d2hec7cbrq','2','Teachers','');
SOME FAILED ATTEMPTS
I am able to join the tables together reasonably well by doing the following:
DROP VIEW IF EXISTS entries;
CREATE VIEW entries AS
SELECT
st.col_entry,
if(st.col_inquiry_name = 'Title', st.col_value, NULL) AS 'Title',
if(st.col_inquiry_name = 'Course', st.col_value, NULL) AS 'Course',
if(bt.col_inquiry_name = 'Description', bt.col_value, NULL) AS 'Description',
if(d.col_inquiry_name = 'Semester', d.col_value, NULL) AS 'Semester',
if(st.col_inquiry_name = 'Location', st.col_value, NULL) AS 'Location',
if(st.col_inquiry_name = 'Teachers', st.col_value, NULL) AS 'Teachers'
FROM smallText st
INNER JOIN bigText bt
ON st.col_entry = bt.col_entry
INNER JOIN date d
ON bt.col_entry = d.col_entry
GROUP BY col_entry;
but here I'm only getting the value of the first row from each table. This is why I tried introducing GROUP_CONCAT
although I haven't had much success with that either:
DROP VIEW IF EXISTS entries;
CREATE VIEW entries AS
SELECT
st.col_entry,
GROUP_CONCAT(if(st.col_inquiry_name = 'Title', st.col_value, NULL)) AS 'Title',
GROUP_CONCAT(if(st.col_inquiry_name = 'Course', st.col_value, NULL)) AS 'Course',
GROUP_CONCAT(if(bt.col_inquiry_name = 'Description', bt.col_value, NULL)) AS 'Description',
GROUP_CONCAT(if(d.col_inquiry_name = 'Semester', d.col_value, NULL)) AS 'Semester',
GROUP_CONCAT(if(st.col_inquiry_name = 'Location', st.col_value, NULL)) AS 'Location',
GROUP_CONCAT(if(st.col_inquiry_name = 'Teachers', st.col_value, NULL)) AS 'Teachers'
FROM smallText st
INNER JOIN bigText bt
ON st.col_entry = bt.col_entry
INNER JOIN date d
ON bt.col_entry = d.col_entry
GROUP BY col_entry;
I'm able to get each column in the view populated with the corresponding values from the tables, but the date and bigText columns are being duplicated according to the orignal row count that they are joined on (7 times).
(Also, as another added level of complexity... I'd like to have it so that the different Teachers would find their way into their own columns as well: Teacher_01, Teacher_02, .. Teacher_05, and I'd guess this probably involves a significant restructuring of what I've got.)
Thanks!
...UPDATE
So, I was able to produce a query which outputs something a bit closer to what I'm looking for, but I can't use it in a view because there is a subquery in the FROM
clause:
SELECT
st.col_entry,
Title,
Course,
Description,
Semester,
Location,
Teachers
FROM smallText st
JOIN (SELECT smallText.col_entry, GROUP_CONCAT(if(smallText.col_inquiry_name = 'Title', smallText.col_value, NULL)) AS 'Title'
FROM smallText GROUP BY smallText.col_entry) a
ON a.col_entry = st.col_entry
JOIN (SELECT smallText.col_entry, GROUP_CONCAT(if(smallText.col_inquiry_name = 'Course', smallText.col_value, NULL)) AS 'Course'
FROM smallText GROUP BY smallText.col_entry) b
ON b.col_entry = st.col_entry
JOIN (SELECT bigText.col_entry, GROUP_CONCAT(if(bigText.col_inquiry_name = 'Description', bigText.col_value, NULL)) AS 'Description'
FROM bigText GROUP BY bigText.col_entry) c
ON c.col_entry = st.col_entry
JOIN (SELECT date.col_entry, GROUP_CONCAT(if(date.col_inquiry_name = 'Semester', date.col_value, NULL)) AS 'Semester'
FROM date GROUP BY date.col_entry) d
ON d.col_entry = st.col_entry
JOIN (SELECT smallText.col_entry, GROUP_CONCAT(if(smallText.col_inquiry_name = 'Location', smallText.col_value, NULL)) AS 'Location'
FROM smallText GROUP BY smallText.col_entry) e
ON e.col_entry = st.col_entry
JOIN (SELECT smallText.col_entry, GROUP_CONCAT(if(smallText.col_inquiry_name = 'Teachers', smallText.col_value, NULL)) AS 'Teachers'
FROM smallText GROUP BY smallText.col_entry) f
ON f.col_entry = st.col_entry
GROUP BY st.col_entry
THE RESULT
The output of this query looks like this:
Entry Title Course Description Semester Location Teachers
---------------------------------------------------------------------------------------------------------------------------------
1 Addition and Subtraction Math Lorem ipsum dolor sit amet... 1294834220 Building 7 NULL
2 Reading Mark Twain Literature Consectetur adipiscing elit... 1327077210 Building 4 NULL
which, with the exception of the null Teachers
column, is basically what I'm looking for (but generated in some way that I can use the query in a view).
Additionally, as I mentioned above, I'd like to be able to pull multiple values for the same inquiry_name
into individual columns. So the final desired output would look like:
THE DESIRED RESULT
Entry Title Course Description Semester Location Teachers_01 Teachers_02 Teachers_03 Teachers_04 Teachers_05
---------------------------------------------------------------------------------------------------------------------------------
1 Addition and Subtraction Math Lorem ipsum dolor sit amet... 1294834220 Building 7 John Jane NULL NULL NULL
2 Reading Mark Twain Literature Consectetur adipiscing elit... 1327077210 Building 4 Billy Bob NULL NULL NULL
Thanks!