Reputation: 5418
I have 4 tables:
CREATE TABLE Category (
Id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
Name VARCHAR(255) NOT NULL,
) Engine=InnoDB;
CREATE TABLE Category_Template (
Id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
Name VARCHAR(255) NOT NULL,
Category_Id INT UNSIGNED NOT NULL,
FOREIGN KEY (Category_Id) REFERENCES Category (Id)
) Engine=InnoDB;
CREATE TABLE Post (
Id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
Post_Name VARCHAR(255) NOT NULL,
Category_Id INT UNSIGNED NOT NULL,
FOREIGN KEY (Category_Id) REFERENCES Category (Id)
) Engine=InnoDB;
CREATE TABLE Post_Fields (
Id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
Post_Id INT UNSIGNED NOT NULL,
Category_Template_Id INT UNSIGNED NOT NULL,
Value VARCHAR(255) NOT NULL,
FOREIGN KEY (Category_Template_Id) REFERENCES Category_Template (Id)
) Engine=InnoDB;
As an example, assume there's a post belonging to the travel category:
INSERT INTO Category
(Id, Name)
VALUES
(1, 'Where to go?')
;
INSERT INTO Category_Template
(Category_Template_Id, Name, Category_Id)
VALUES
(1, 'Budget', 1),
(2, 'Location', 1),
(3, 'Time', 1)
;
INSERT INTO Post
(PostId, Post_Name, Category_Id)
VALUES
(1, 'America is good', 1),
(2, 'Hot Travel', 1)
;
INSERT INTO Post_Fields
(Id, Post_Id, Category_Template_Id, Value)
VALUES
(1, 1, 1, '1000 $'),
(1, 1, 2, 'New York'),
(1, 1, 3, 'January 2012'),
(1, 2, 1, '2000 $'),
(1, 2, 2, 'Brasil'),
(1, 2, 3, 'May 2012')
;
I want to run an SQL query which will list all posts that belong to a given category and list all fields for those posts as separate columns, with the category template names as column names. The results should be something like:
Post Id Post_Name Budget Location Time 1 America is good 1000 $ New York January 2012 2 Hot Travel 2000 $ Brasil May 2012
My problem is that category templates for different categories have different names, making it hard to write a single general use query. For example, a category for traveling can have 3 templates (location, budget, time) whereas a category for books have 4 templates (abstract, content, author_bio, summary). How can I write a statement that turns one column into multiple columns (based on the value in the same row but in another column), when the exact number of output columns will vary? Similarly, how can I write a statement that turns one column into multiple column headers, considering that the number of output columns will vary?
Upvotes: 1
Views: 175
Reputation: 3747
SELECT Post_Id as `Post Id`, Post_Name,
(SELECT Value FROM Post_Fields WHERE Category_Template_Id=1
AND Post_Fields.Post_Id=Post.Post_id) AS `Budget`,
... more of the same ...
FROM Post WHERE Post_Id = 1
Upvotes: 1