Saturday, June 8, 2013

MySQLにおけるピボットテーブルの例

Original post: http://anothermysqldba.blogspot.com/2013/06/pivot-tables-example-in-mysql.html

私が上で頼まれたforums.mysql.comコースなどを追跡するためにサブスクリプションテーブルを構築する方法のサイト 

それはここに完全な例を投稿する方が簡単だった、それが迅速簡単な例ですが、あなたのアイデアを得る。 

ここのコンセプトはシンプルです。 
私たちは、必要なときに、我々はその後、別の列に戻って引き出しできる行に情報を格納する。 

要求は、学生やコースのサブスクリプションのためだった.... 

最初に私はいくつかのテーブルとデータを建て... 



CREATE TABLE `details` (
`details_id` int(11) NOT NULL AUTO_INCREMENT,
`details_label` varchar(100) DEFAULT NULL,
PRIMARY KEY (`details_id`)
) ENGINE=InnoDB;
INSERT INTO details VALUES (1,'First Name') , (2, 'Last Name') ;

CREATE TABLE `subjects` (
`subject_id` int(11) NOT NULL AUTO_INCREMENT,
`subject` enum('History','English','Geography','Mathematics','Science','Social Studies','Foreign Languages','Visual and Performing Arts') DEFAULT NULL,
`subject_detail` varchar(255) DEFAULT NULL,
PRIMARY KEY (`subject_id`)
) ENGINE=InnoDB;
INSERT INTO subjects VALUES (1,'Mathematics', 'Algebra') , (2,'History', '1826-1926') , (3,'Geography', ' Africa Studies') ;

CREATE TABLE `student` (
`student_id` int(11) NOT NULL AUTO_INCREMENT,
`email` varchar(150) DEFAULT NULL,
`student_key` varchar(20) DEFAULT NULL,
`date_updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`student_id`)
) ENGINE=InnoDB;
INSERT INTO student (`student_id` ,`email`,`student_key`) VALUES (1,'foobar@gmail.com','iasdjf');

CREATE TABLE `student_details` (
`student_details_id` int(11) NOT NULL AUTO_INCREMENT,
`student_id` int(11) DEFAULT 0,
`details_id` int(11) DEFAULT 0,
`details_value` varchar(255) DEFAULT NULL,
`date_updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`student_details_id`)
) ENGINE=InnoDB;
INSERT INTO student_details VALUES (NULL,1,1,'John',NOW()) , (NULL,1,2,'Smith',NOW()) ;

CREATE TABLE `courselist` (
`courselist_id` int(11) NOT NULL AUTO_INCREMENT,
`student_id` int(11) DEFAULT 0,
`subject_id` int(11) DEFAULT NULL,
`status` enum('Waitlisted','Subscribed','Denied') DEFAULT NULL,
`date_updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`courselist_id`)
) ENGINE=InnoDB;
INSERT INTO courselist VALUES ( NULL,1, 1 , 'Waitlisted' , NOW() ) , ( NULL,1, 2 , 'Subscribed' , NOW() ) , ( NULL,1, 3 , 'Denied' , NOW() ) ;

最初だけ生徒に関する情報を引き出す: 


> SELECT s.student_id , d.details_label , sd.details_value
-> FROM student s
-> INNER JOIN student_details sd ON s.student_id = sd.student_id
-> INNER JOIN details d ON sd.details_id = d.details_id;
+------------+---------------+---------------+
| student_id | details_label | details_value |
+------------+---------------+---------------+
| 1 | First Name | John |
| 1 | Last Name | Smith |
+------------+---------------+---------------+
2 rows in set (0.00 sec) 


我々はより多くを掘るし、情報を追加し続けることができます... 


> SELECT s.student_id , d.details_label , sd.details_value , c.status, j.subject, j.subject_detail
-> FROM student s
-> INNER JOIN student_details sd ON s.student_id = sd.student_id
-> INNER JOIN details d ON sd.details_id = d.details_id
-> INNER JOIN courselist c ON s.student_id = c.student_id
-> INNER JOIN subjects j ON j.subject_id = c.subject_id
-> ;
+------------+---------------+---------------+------------+-------------+-----------------+
| student_id | details_label | details_value | status | subject | subject_detail |
+------------+---------------+---------------+------------+-------------+-----------------+
| 1 | First Name | John | Waitlisted | Mathematics | Algebra |
| 1 | Last Name | Smith | Waitlisted | Mathematics | Algebra |
| 1 | First Name | John | Subscribed | History | 1826-1926 |
| 1 | Last Name | Smith | Subscribed | History | 1826-1926 |
| 1 | First Name | John | Denied | Geography | Africa Studies |
| 1 | Last Name | Smith | Denied | Geography | Africa Studies |
+------------+---------------+---------------+------------+-------------+-----------------+
6 rows in set (0.00 sec) 



それはしかし非常に便利かきれいではない... 
だから、これはまさに我々が望むもの引っ張ってやり直し... 


> SELECT s.student_id ,sd1.details_value as FIRST_NAME, sd2.details_value as LAST_NAME, c.status, j.subject, j.subject_detail
-> FROM student s
-> INNER JOIN student_details sd1 ON s.student_id = sd1.student_id AND sd1.details_id = 1
-> INNER JOIN student_details sd2 ON s.student_id = sd2.student_id AND sd2.details_id = 2
-> INNER JOIN courselist c ON s.student_id = c.student_id
-> INNER JOIN subjects j ON j.subject_id = c.subject_id
-> ;
+------------+------------+-----------+------------+-------------+-----------------+
| student_id | FIRST_NAME | LAST_NAME | status | subject | subject_detail |
+------------+------------+-----------+------------+-------------+-----------------+
| 1 | John | Smith | Waitlisted | Mathematics | Algebra |
| 1 | John | Smith | Subscribed | History | 1826-1926 |
| 1 | John | Smith | Denied | Geography | Africa Studies |
+------------+------------+-----------+------------+-------------+-----------------+
3 rows in set (0.00 sec)