2013-10-06 7 views
2

Я работаю над своим проектом в php [управление системой посещаемости учащихся]. У меня есть список студентов вместе с их уникальным id [jntuno], и мне нужно создать базу данных в mysql для хранения ежедневной посещаемости каждого ученика для каждого предмета. Так что я создал свои таблицы таким образом:Создание столбцов таблицы с использованием строк другого

У меня есть таблица students в MySQL со следующими полями и в нем данных:

my table contents

теперь я хочу, чтобы создать новую таблицу с каждым из значения в поле jntuno в качестве столбцов моей новой таблицы.

Я хочу, чтобы моя новая таблица [назовем его attendance], чтобы столбцы, как это:

+------------+-----------+----------+-----------+-----------+ 
|11341A0501 |11341A0502 |11341A0503|11341A0504 |11341A0505 |......  
+------------+-----------+----------+-----------+-----------+ 
|   |   |   |   |   | 

Как сделать это в MySQL?

Я позже добавить 3 поля в attendance таблице а именно:

->date [дата, на которой преподается конкретный предмет],

->subject [название предмета преподается ] и

->hours taught [количество часов, в течение которого конкретный предмет преподается (может быть 1 или 2, или 3 ... до 6)]

каждых subject преподавал на конкретном date будет добавлять новый row к attendance таблице

Пример:

+------------+-----------+-----------------+------------+-----------+----------+-----------+-----------+ 
|date  |subject | classes taught |11341A0501 |11341A0502 |11341A0503|11341A0504 |11341A0505 |..  
+------------+-----------+-----------------+------------+-----------+----------+-----------+-----------+ 
|2013-09-31 |OOPS  |3    |2   |3   |0   |1   |3   | 

Я выбираю таблицы в этом случае так, что запись посещаемости в таблицу будет больше Быстрее.

Но многие называют это ПЛОХАЯ СТРУКТУРА БАЗА ДАННЫХ. Поэтому, пожалуйста, предложите мне, если есть какой-то другой хороший и эффективный дизайн базы данных для моей проблемы

+2

Обычно это не хорошо спроектированная модель. У вас есть нормализованная схема базы данных? –

+0

Есть ли альтернатива для этого типа проблем? если да, пожалуйста, предложите мне –

+0

Если вы хотите хранить данные об учениках, просто добавьте 'student_id' в свою новую таблицу. Определите его как * внешний ключ * в таблице 'student'. Возможно, [это] (http://agiledata.org/essays/dataNormalization.html) может вам помочь. –

ответ

2

Создать новую таблицу со следующими утверждениями:

select @s:=concat('create table students_col (',group_concat(jntunno,' CHAR(10)' order by slno),')') from students; 
prepare stmt from @s; 
execute stmt; 
deallocate prepare stmt; 

наблюдать, как CREATE TABLE строится с помощью group_concat

Demo: SQL Fiddle

В случае, если вы хотите вставить имена, это заявление к нему:

select @s:=concat('insert into students_col values (',group_concat(concat('"',name,'"') order by slno),')') from students; 
prepare stmt from @s; 
execute stmt; 
deallocate prepare stmt; 
select * from students_col; 

Вот весь мой след:

mysql> drop table if exists students; 
Query OK, 0 rows affected (0.00 sec) 

mysql> create table students (slno integer, jntunno char(10), name varchar(50)); 
Query OK, 0 rows affected (0.07 sec) 

mysql> insert into students values (1,'1134A0501','ADARI GOPI'); 
Query OK, 1 row affected (0.00 sec) 

mysql> insert into students values (2,'1134A0502','BALU'); 
Query OK, 1 row affected (0.00 sec) 

mysql> insert into students values (3,'1134A0503','GEETHA'); 
Query OK, 1 row affected (0.00 sec) 

mysql> drop table if exists students_col; 
Query OK, 0 rows affected (0.00 sec) 

mysql> select @s:=concat('create table students_col (',group_concat(jntunno,' CHAR(10)' order by slno),')') from students; 
+-----------------------------------------------------------------------------------------------+ 
| @s:=concat('create table students_col (',group_concat(jntunno,' CHAR(10)' order by slno),')') | 
+-----------------------------------------------------------------------------------------------+ 
| create table students_col (1134A0501 CHAR(10),1134A0502 CHAR(10),1134A0503 CHAR(10))   | 
+-----------------------------------------------------------------------------------------------+ 
1 row in set (0.00 sec) 

mysql> prepare stmt from @s; 
Query OK, 0 rows affected (0.00 sec) 
Statement prepared 

mysql> execute stmt; 
Query OK, 0 rows affected (0.21 sec) 

mysql> deallocate prepare stmt; 
Query OK, 0 rows affected (0.01 sec) 

mysql> 
mysql> select @s:=concat('insert into students_col values (',group_concat(concat('"',name,'"') order by slno),')') from students; 
+------------------------------------------------------------------------------------------------------+ 
| @s:=concat('insert into students_col values (',group_concat(concat('"',name,'"') order by slno),')') | 
+------------------------------------------------------------------------------------------------------+ 
| insert into students_col values ("ADARI GOPI","BALU","GEETHA")          | 
+------------------------------------------------------------------------------------------------------+ 
1 row in set (0.00 sec) 

mysql> prepare stmt from @s; 
Query OK, 0 rows affected (0.00 sec) 
Statement prepared 

mysql> execute stmt; 
Query OK, 1 row affected (0.00 sec) 

mysql> deallocate prepare stmt; 
Query OK, 0 rows affected (0.00 sec) 

mysql> 
mysql> select * from students_col; 
+------------+-----------+-----------+ 
| 1134A0501 | 1134A0502 | 1134A0503 | 
+------------+-----------+-----------+ 
| ADARI GOPI | BALU  | GEETHA | 
+------------+-----------+-----------+ 
1 row in set (0.00 sec) 

mysql> 
+0

, который был потрясающим! .... можете ли вы также предложить мне лучший дизайн базы данных для этого типа случая, пожалуйста! –

+0

Я задавался вопросом, зачем вам столько столбцов. Я бы предложил вам что-то, если бы знал, что вы на самом деле собираетесь делать. Честно говоря, я бы не создал такую ​​таблицу. Предположим, вы хотите заполнить таблицу HTML таким образом, чтобы я лучше прочитал существующую таблицу и построил вывод HTML из нее, например, в PHP или на каком-либо другом сервере. – hol

+0

проверьте мой вопрос снова @hol.Я обновил описание –

0
create table new_table 
select distinct jntuno from students; 

или

create table new_table (jntuno varchar(10)); 
insert into new_table 
select distinct jntuno from students; 
+0

. Полученное вами решение создает новую таблицу с «jntuno» в качестве столбца в ней и импортирует все значения этого поля из таблицы «students». .. это не то, что я хотел! ... Я хочу, чтобы каждое из значений строки было столбцом моей новой таблицы. –

+0

Я вижу. Не делай этого. Это действительно плохой дизайн БД. –

+0

Есть ли альтернатива для этого типа проблем? –

0

попробовать

create table new_table (jntuno varchar(10),fieldsname varchar(10)); 
insert into new_table(jntuno,fieldsname) 
values(select distinct jntuno from s tudents,'test'); 
+0

это не решает мою цель @sunysen –

+0

Я вижу , Не делай этого. Это действительно плохой дизайн БД – sunysen

+0

«Не реляционный» не означает «плохой дизайн». Это зависит от того, что ему нужно делать. –

3

Эта процедура сделает работу:

DELIMITER || 
DROP PROCEDURE IF EXISTS `test`.`pivot`; 
CREATE PROCEDURE `test`.`pivot`() 
    MODIFIES SQL DATA 
BEGIN 
    DROP TABLE IF EXISTS `test`.`new_table`; 
    SELECT GROUP_CONCAT(CONCAT(`jntunno`, ' CHAR(10) NOT NULL') SEPARATOR ', ') FROM `test`.`students` INTO @sql; 
    SET @sql := CONCAT('CREATE TABLE `test`.`new_table` (', @sql, ') ENGINE=InnoDB;'); 
    PREPARE stmt FROM @sql; 
    EXECUTE stmt; 
    DEALLOCATE PREPARE stmt; 
    SET @sql := NULL; 
END; 
|| 
DELIMITER ; 

Если вы не можете использовать память вы можете легко перевести этот код на PHP или на любой язык, который вы используете.

+0

Это было потрясающе! .... можете ли вы также предложить мне лучший дизайн базы данных для этого типа случая, пожалуйста! –

+0

Дизайн, который вы хотели использовать, может быть хорошим или ужасным, это зависит от того, что вам нужно сделать. Базы данных должны быть разработаны для быстрого ответа на ваши запросы. Поэтому мне (или кому-то) действительно нужно что-то узнать о ваших запросах, прежде чем предлагать дизайн –

0

Я собираюсь попробовать ответ на ваш вопрос о том, как лучше дизайн этой БД:

Объяснение: Вместо того, чтобы иметь столбец для каждого студента и Я принимаю строку за каждый день, вы должны настроить таблицу для каждой строки для каждого ученика x каждый день, и вы можете использовать внешние ключи для обеспечения целостности данных.

Основная причина этого - это, как правило, что-то вроде числа студентов не является статическим числом. Чтобы оптимизировать использование данных в такой конфигурации, вам по существу нужно будет воссоздавать таблицу каждый раз, когда студент добавляется или удаляется. Итак, если вы начинаете с 30 учеников, тогда у вас есть таблица с 30 столбцами, если тогда количество учеников падает до 15 при каждом добавлении записи, вы создаете 15 неиспользуемых значений, и это постепенно будет занимать гораздо больше места, чем вам действительно нужно.

Решение: Если вы структурировать таблицу посещаемости, как это:

attendance ID | JNTUNO | Date | Subject | Hours 

Посещаемость идентификатор будет просто уникальный идентификатор строки, я хотел бы предложить либо справ или автоматическое приращение Int

JNTUNO будет иностранным ключом, указав обратно на таблицу вашего ученика

В этом случае по сценарию, который я представил ранее, с 30 учениками вы будете добавлять 30 строк каждый день с 5 значениями каждый, но когда ваш номер студента s изменяется до 15, вы добавляете только 15 строк.

Я не очень хорошо разбираюсь в синтаксисе MYSQL, но если вы хотите, чтобы я попытался собрать конкретную реализацию, если мои объяснения не ясны; просто дай мне знать.

0
declare @s as varchar(8000); 
declare @s2 as varchar(25); 
set @s ='create table attendance ('; 
declare s1 cursor 
for 
select jntunno from students 
OPEN s1 
    fetch next from s1 into @s2 
    set @s = @s +'['[email protected] +'] numeric(4,2)' 
    fetch next from s1 into @s2 
    WHILE @@FETCH_STATUS = 0 
    BEGIN 
     set @s = @s +',['[email protected] +'] numeric(4,2)' 
     fetch next from s1 into @s2 
    end 
CLOSE s1 -- close the cursor 
DEALLOCATE s1 
set @s = @s+')' 
exec(@s) 
0

Вы не хотите добавлять столбцы каждый раз, когда вы добавляете ученика.

Я бы дизайн это так:

Table: Attendance 
    Columns: 
     Date 
     Subject 
     ClassNumber 
     Missed_jntuno 

Затем добавьте строку для каждого студента/класса комбо, который пропустил (или, если учащиеся пропускают больше, чем они посещают, вы можете перевернуть, что на поле Attended_jntuno и добавьте строку, когда они сделают ее в классе, или если вы действительно чувствуете себя максимально полным, всегда пишите строку для каждого ученика, а затем добавляете другой бит/булевский столбец для участия или нет).

Одним из преимуществ этого способа является то, что вы можете видеть, какие классы получили, какие студенты в дополнение к ежедневной сумме.Другое дело, что это гораздо более дружелюбное отношение к таким вещам, как кубы OLAP для гибкой отчетности.

0

Базовый дизайн базы данных сейчас подпрыгивает и кричит вам в лицо: «Вы делаете это неправильно!».

Что вы пытаетесь сделать здесь, это положить много-много отношений в 1 таблицу, в то время как оно должно быть в 3 таблицах.

Что вы должны сделать, это сохранить таблицу учеников как есть и добавить таблицу subjects с 1 строкой для каждого объекта, но не включая дату.

Затем вы хотите получить еще одну таблицу Attendance с ссылочным столбцом для идентификатора студента, ссылочного столбца к объекту ID, поля даты и поля присутствия.

То, что вы пытаетесь сделать прямо сейчас, пытается сохранить то, что в основном является изменчивой информацией в ваших метаданных о вашей таблице, чего вы никогда не должны делать. Например, что, если у вас есть студент, присоединитесь к своей школе 1 неделю в классе? то ваш стол неожиданно получает дополнительную колонку без значений за первую неделю.

Кроме того, ваша система означает, что запросы к базе данных намного сложнее, поскольку вы храните данные, которые хотите фильтровать в заголовке столбца. Другие люди здесь дали ряд причин, почему это плохая идея.

Смежные вопросы