Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Połącz dwie tabele (w relacji 1-M), gdzie druga tabela musi zostać „spłaszczona” w jeden wiersz

select s.id,s.name,
max(case when e.course_id = 55 then complete else null end) as c55,
max(case when e.course_id = 66 then complete else null end) as c66,
max(case when e.course_id = 77 then complete else null end) as c77
from student as s
left join enrollment as e
on s.id = e.student_id
group by s.id

@Chris. Korzystając z procedury składowanej, możesz nawet utworzyć dynamiczną tabelę przestawną bez znajomości liczby kolumn. To jest link

http://forum.html.it/forum/showthread.php ?s=&threadid=1456236

odpowiedzi na podobny problem na włoskim forum. Istnieje kompletny przykład, który może pomóc w zrozumieniu stojącej za tym logiki. :)

EDYTUJ. Aktualizacja za pomocą MYSQL DYNAMIC VIEW

To jest mój startowy zrzut:

/*Table structure for table `student` */

drop table if exists `student`;

create table `student` (
  `id` int(10) unsigned not null auto_increment,
  `name` varchar(50) default null,
  primary key (`id`)
) engine=myisam;

/*Data for the table `student` */

insert  into `student`(`id`,`name`) values (1,'chris');
insert  into `student`(`id`,`name`) values (2,'joe');
insert  into `student`(`id`,`name`) values (3,'jack');

drop table if exists enrollment;

create table `enrollment` (
  `enrollment_id` int(11) auto_increment primary key,
  `student_id` int(11) default null,
  `course_id` int(11) default null,
  `complete` varchar(50) default null
) engine=myisam auto_increment=8 default charset=latin1;

/*Data for the table `enrollment` */

insert  into `enrollment`(`enrollment_id`,`student_id`,`course_id`,`complete`) values (1,1,55,'true');
insert  into `enrollment`(`enrollment_id`,`student_id`,`course_id`,`complete`) values (2,1,66,'true');
insert  into `enrollment`(`enrollment_id`,`student_id`,`course_id`,`complete`) values (3,1,77,'true');
insert  into `enrollment`(`enrollment_id`,`student_id`,`course_id`,`complete`) values (4,2,55,'true');
insert  into `enrollment`(`enrollment_id`,`student_id`,`course_id`,`complete`) values (5,2,66,'false');
insert  into `enrollment`(`enrollment_id`,`student_id`,`course_id`,`complete`) values (6,3,55,'false');
insert  into `enrollment`(`enrollment_id`,`student_id`,`course_id`,`complete`) values (7,3,66,'true');

a to jest procedura składowana dla widoku dynamicznego:

delimiter //
drop procedure if exists dynamic_view//
create procedure dynamic_view()
begin
declare finish int default 0;
declare cid int;
declare str varchar(10000) default "select s.id,s.name,";
declare curs cursor for select course_id from enrollment group by course_id;
declare continue handler for not found set finish = 1;
open curs;
my_loop:loop
fetch curs into cid;
if finish = 1 then
leave my_loop;
end if;
set str = concat(str, "max(case when e.course_id = ",cid," then complete else null end) as course_",cid,",");
end loop;
close curs;
set str = substr(str,1,char_length(str)-1);
set @str = concat(str," from student as s
            left join enrollment as e
            on s.id = e.student_id
            group by s.id");
prepare stmt from @str;
execute stmt;
deallocate prepare stmt;
-- select str;
end;//
delimiter ;

Teraz nazwijmy to

mysql> call dynamic_view();
+----+-------+-----------+-----------+-----------+
| id | name  | course_55 | course_66 | course_77 |
+----+-------+-----------+-----------+-----------+
|  1 | chris | true      | true      | true      |
|  2 | joe   | true      | false     | NULL      |
|  3 | jack  | false     | true      | NULL      |
+----+-------+-----------+-----------+-----------+
3 rows in set (0.00 sec)

Query OK, 0 rows affected (0.05 sec)

Teraz wstawiamy kolejne dwa rekordy z dwoma różnymi kursami:

insert  into `enrollment`(`student_id`,`course_id`,`complete`) values (1,88,'true');
insert  into `enrollment`(`student_id`,`course_id`,`complete`) values (3,99,'true');

i przypominamy procedurę. Oto wynik:

mysql> call dynamic_view();
+----+-------+-----------+-----------+-----------+-----------+-----------+
| id | name  | course_55 | course_66 | course_77 | course_88 | course_99 |
+----+-------+-----------+-----------+-----------+-----------+-----------+
|  1 | chris | true      | true      | true      | true      | NULL      |
|  2 | joe   | true      | false     | NULL      | NULL      | NULL      |
|  3 | jack  | false     | true      | NULL      | NULL      | true      |
+----+-------+-----------+-----------+-----------+-----------+-----------+
3 rows in set (0.00 sec)

Query OK, 0 rows affected (0.02 sec)

To wszystko. :)




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wstaw wartość NULL do kolumny INT

  2. Korzystanie z widoków MySQL

  3. Jak wykonać mysqldump bez pytania o hasło?

  4. Podczas korzystania z Entity Framework z MySQL znaki Unicode są zastępowane znakami podstawowymi

  5. Jak zresetować słowa stop w MYSQL?