PostgreSQL соединение таблицы - PullRequest
2 голосов
/ 30 мая 2020

У меня есть база данных посещаемости лекций как универмаг. В качестве одного из представлений мне пришла в голову идея, что я могу сделать представление missed_lectures со всеми записями типов явки «Не посещено» или «Больной». Когда я делаю этот запрос, он возвращает 2,5 тыс. Строк, что неверно.

Запрос выглядит так

CREATE OR REPLACE VIEW missed_lectures AS
SELECT CONCAT(s.student_name, ' ', s.student_surname) AS "Student", sc.course_title AS "Study course", atp.attendance_type AS "Attendance type", a.record_date AS "Date"
FROM students AS s, study_courses AS sc, attendance_type AS atp, attendance AS a
WHERE
s.student_id=a.student_id AND
sc.course_id=a.course_id AND
a.attendance_type_id=atp.attendance_type_id AND
a.attendance_type_id=(SELECT attendance_type_id FROM attendance_type WHERE attendacne_type='Sick') OR
a.attendance_type_id=(SELECT attendance_type_id FROM attendance_type WHERE attendance_type='Not attended')
GROUP BY s.student_name, s.student_surname, sc.course_title, atp.attendance_type, a.record_date;

Это последний запрос, который я придумал, но, как я упоминал ранее, он возвращает 2,5 тыс. Строк с неверными данными. Может ли кто-нибудь заметить здесь проблему?

EDIT: table student is

CREATE TABLE students(
student_id serial PRIMARY KEY NOT NULL,
student_name VARCHAR(30) NOT NULL,
student_surname VARCHAR(35) NOT NULL,
matriculation_number VARCHAR(7) NOT NULL CHECK(matriculation_number ~ '[A-Z]{2}[0-9]{5}'),
faculty_id INT NOT NULL,
course INT NOT NULL,
phone_number CHAR(8) CHECK(phone_number ~ '^2{1}[0-9]{7}'),
email VARCHAR(35),
gender VARCHAR(10)
);

образцы данных:

INSERT INTO students (student_name, student_surname, matriculation_number, faculty_id, course, phone_number, email, gender)
VALUES
('Sandis','Bērziņš','IT19047',7,1,'25404213','sandis.berzins@gmail.com','man'),
('Einārs','Kļaviņš','IT19045',7,1,'24354654','einars.klavins@gmail.com','man'),
('Jana','Lapa','EF18034',8,2,'26224941','lapajana@inbox.lv','woman'),
('Sanija','Bērza','EF18034',8,2,'24543433','berzasanija@inbox.lv','woman'),
('Valdis','Sijāts','TF19034',4,1,'25456545','valdis.sijats@gmail.com','man'),
('Jānis','Bānis','IT17034',7,3,'24658595','banis.janis@inbox.lv','man');

table study_courses

CREATE TABLE study_courses(
course_id serial PRIMARY KEY NOT NULL,
course_title VARCHAR(55) NOT NULL,
course_code VARCHAR(8) NOT NULL CHECK(course_code ~ '[a-zA-Z]{4}[0-9]{4}'),
credit_points INT
);

примерные данные:

INSERT INTO study_courses (course_title, course_code, credit_points)
VALUES
('Fundamentals of Law','JurZ2005',2),
('Database technologies II','DatZ2005',2),
('Product processing','PārZ3049',4),
('Arhitecture','Arhi3063',3),
('Forest soils','LauZ1015',4);

Тип_посещаемости стола:

CREATE TABLE attendance_type(
attendance_type_id serial PRIMARY KEY NOT NULL,
attendance_type VARCHAR(15) NOT NULL
);

образец данных:

INSERT INTO attendance_type (attendance_type)
VALUES
('Attended'),
('Not attended'),
('Late'),
('Sick');

посещаемость стола:

CREATE TABLE attendance(
record_id serial PRIMARY KEY NOT NULL,
student_id INT NOT NULL,
course_id INT NOT NULL,
attendance_type_id INT NOT NULL,
lecturer_id INT,
lecture_type_id INT NOT NULL,
audience_id INT NOT NULL,
record_date DATE NOT NULL
);

образцы данных:

INSERT INTO attendance (student_id, course_id, attendance_type_id, lecturer_id, lecture_type_id, audience_id, record_date)
VALUES
(1,2,1,1,1,14,'20-05-2020'),
(2,2,1,1,1,14,'20-05-2020'),
(6,9,1,13,2,2,'20-05-2020'),
(22,9,2,13,2,2,'20-05-2020'),
(24,9,3,13,2,2,'20-05-2020');

Надеюсь, это поможет.

1 Ответ

0 голосов
/ 30 мая 2020

Проблема в том, что условие OR в вашем предложении WHERE.
Вы должны заключить его в круглые скобки, если собираетесь делать это таким образом.
Однако вы уже запрашиваете attendance_type таблица, поэтому вы можете просто использовать ее для фильтрации этих двух условий типа посещаемости.

SELECT 
    CONCAT(s.student_name, ' ', s.student_surname) AS "Student", 
    sc.course_title AS "Study course", 
    atp.attendance_type AS "Attendance type", 
    a.record_date AS "Date"
FROM 
    students AS s, study_courses AS sc, 
    attendance_type AS atp, attendance AS a
WHERE
    s.student_id=a.student_id AND
    sc.course_id=a.course_id AND
    a.attendance_type_id=atp.attendance_type_id AND
    -- filter for these two conditions without subqueries
    atp.attendance_type in ('Sick','Not attended') 
GROUP BY 
    CONCAT(s.student_name, ' ', s.student_surname), sc.course_title, 
    atp.attendance_type, a.record_date;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...