используйте CASE с SQLITE для сопоставления полей

У меня есть база данных SQLite с именами учеников. У каждого ученика разные классы. У меня есть таблица с оценками и классами учеников, а также другая таблица, которая определяет класс по типу. Я хочу выполнить запрос (который я сохраню в формате CSV для использования в OpenOffice в качестве документа Excel для слияния). Мне нужно указать оценки учащегося по математике, истории, естественным наукам и английскому языку. Однако некоторые учащиеся посещают более одного занятия по математике, естественным наукам, английскому языку или истории. (Как) я могу создать оператор CASE (и, возможно, представление), что, если действительно существует более одного класса Math, он может быть указан в представлении как Math_Class_2, например?


person d-cubed    schedule 17.07.2010    source источник
comment
Я не совсем уверен, что вы имеете в виду. Можем ли мы получить некоторые основные определения таблиц и пример желаемого результата, пожалуйста?   -  person MPelletier    schedule 20.07.2010
comment
Я сделал обходной путь Python ... Не совсем то, что я хотел, но достаточно близко. Можно ли воспроизвести следующий код в виде представлений, созданных с помощью операторов case: cursor.execute('SELECT DISTINCT student_id, course_title, final_grade FROM math_class') for row in cursor: student_id = row[0] course_title = row[1] final_grade = row[2] if student_id == old_student_id: if student_id != second_round_id: ... write_string = "INSERT INTO math_class_2_2010 ...   -  person d-cubed    schedule 22.07.2010
comment
Есть таблица: TABLE eoygrades_2010 (student_id INTEGER CHAR(6) NOT NULL, course_title VARCHAR(16), класс INTEGER CHAR(3)); и я хотел создать оператор case для отображения математического класса, если он не отображался. Вместо: Эдди, Алгебра, 90 Эдди, Геометрия, 80 Я мог бы напечатать одну строку Эдди, Алгебра, 90, Геометрия, 80, а для тех, у кого только один математический класс: Сьюзи, Pre-Cal, 85,,   -  person d-cubed    schedule 22.07.2010
comment
По сути, обходной путь Python создает дополнительную таблицу для каждого дополнительного класса. Могли ли аналогичные выходные данные (не новые таблицы) быть созданы только с помощью операторов SQL?   -  person d-cubed    schedule 22.07.2010
comment
Ах! Я понимаю. Что ж, к сожалению для вас, я не верю, что в SQLite есть оператор CASE. Создание нескольких запросов может быть не такой уж плохой идеей...   -  person MPelletier    schedule 23.07.2010
comment
В SQLite есть оператор case (сейчас). Я помнил, что в нем не было оператора CASE (или, по крайней мере, не близко к уровню MySQL), но, похоже, теперь есть хотя бы некоторые базовые функции CASE. Кто знает, может быть, остальные операторы JOIN появятся, когда никто не смотрит...   -  person d-cubed    schedule 23.07.2010
comment
О боже, да! sqlite.org/lang_expr.html   -  person MPelletier    schedule 23.07.2010


Ответы (2)


Идея состоит в том, чтобы SQL выполнял работу, а не делал ее за него.

Предполагая три таблицы:

Студент (Номер Студента, Имя Студента)

Класс (Номер Класса, Имя Класса)

Результат (№ Класса, № Студента, Оценка)

Запрос будет:

SELECT StudentName, group_concat(ClassName || "," || Grade)
FROM Student
INNER JOIN Result ON Result.StudentNo=Student.StudentNo
INNER JOIN Class ON Result.ClassNo=Class.ClassNo
GROUP BY Student.Studentno;

(group_concat — еще одно позднее дополнение к SQlite. Присутствует в версии 3.7).

Вот дамп всех команд, которые я использовал:

CREATE TABLE [Student] (
[StudentNo] INTEGER  NOT NULL PRIMARY KEY,
[StudentName] TEXT  NULL
);
INSERT INTO "Student" VALUES(1,'Jimmy');
INSERT INTO "Student" VALUES(2,'Bob');
INSERT INTO "Student" VALUES(3,'Anna');
CREATE TABLE [Class] (
[ClassNo] INTEGER  NOT NULL PRIMARY KEY,
[ClassName] TEXT  NULL
);
INSERT INTO "Class" VALUES(1,'English');
INSERT INTO "Class" VALUES(2,'Algebra');
INSERT INTO "Class" VALUES(3,'Geometry');
INSERT INTO "Class" VALUES(4,'Pre-Cal');
CREATE TABLE [Result] (
[StudentNo] INTEGER  NOT NULL,
[ClassNo] INTEGER  NOT NULL,
[Grade] INTEGER  NOT NULL,
PRIMARY KEY ([StudentNo],[ClassNo])
);
INSERT INTO "Result" VALUES(1,1,70);
INSERT INTO "Result" VALUES(1,2,75);
INSERT INTO "Result" VALUES(1,3,80);
INSERT INTO "Result" VALUES(2,1,85);
INSERT INTO "Result" VALUES(2,2,90);
INSERT INTO "Result" VALUES(3,4,95);

Выполнение запроса возвращает это (вы можете настроить разделительный символ):

Jimmy,English,70,Algebra,75,Geometry,80

Bob,English,85,Algebra,90

Anna,Pre-Cal,95

person MPelletier    schedule 23.07.2010

Мои два цента...

В настоящее время я работаю над приложением для Android, которое использует базу данных sqlite. Мне нужно было использовать оператор CASE, и он сработал!!!.

В таблице есть столбец со значением частоты времени в миллисекундах, но для конечного пользователя мне нужно было показать информацию в более простом для понимания виде, поэтому я использовал это выражение sql (кстати, это выражение составлено программно... это не жестко запрограммировано) :-p

SELECT 
case when alarm_time_frequency='0' then 'Not Used' 
when alarm_time_frequency='300000' then '5 min' 
when alarm_time_frequency='600000' then '10 min' 
when alarm_time_frequency='900000' then '15 min' 
when alarm_time_frequency='1800000' then '30 min' 
when alarm_time_frequency='3600000' then '1 hour' 
when alarm_time_frequency='7200000' then '2 hours' 
when alarm_time_frequency='10800000' then '3 hours' 
when alarm_time_frequency='14400000' then '4 hours' 
when alarm_time_frequency='21600000' then '6 hours' 
when alarm_time_frequency='28800000' then '8 hours' 
when alarm_time_frequency='43200000' then '12 hours' 
when alarm_time_frequency='86400000' then '24 hours' 
end 
as alarm_time_frequency FROM ALARMS 

I hope this helps...
person monn3t    schedule 23.07.2010