2013-08-16 3 views
1

У меня есть 4 таблицы:SQLite - Выбор записи, которые не имеют аналогов в другой таблице

CREATE TABLE People(
    id integer primary key autoincrement, 
    'First Name' text, 
    'Last Name' text, 
); 

CREATE TABLE Courses(
    id integer primary key autoincrement, 
    'Course Name' text, 
    'Course Refresh Rate' integer 
); 

CREATE TABLE [Course Enrolment](
    'Person ID' integer, 
    'Course ID' integer, 
    FOREIGN KEY ('Person ID') REFERENCES People(id), 
    FOREIGN KEY ('Course ID') REFERENCES Courses(id) 
); 

CREATE TABLE [Course Participation](
    'Person ID' integer, 
    'Course ID' integer, 
    'Date Taken' text, 
    FOREIGN KEY ('Person ID') REFERENCES People(id), 
    FOREIGN KEY ('Course ID') REFERENCES Courses(id) 
); 

Я пытаюсь выбрать людей, которые зачислены на курс, но либо никогда не взяли курс (и поэтому не имеют записи в таблице «Участие в курсе») или прошли курс больше, чем «Частота обновления курса» несколько лет назад. Я написал инструкцию select, но она не работает должным образом.

SELECT [First Name], 
     [Last Name] 
    FROM people AS p 
     LEFT JOIN courses AS c 
     JOIN [course enrolment] AS ce 
     JOIN [course participation] AS cp 
     ON p.id = ce.[Person ID] 
     AND p.id = cp.[Person ID] 
     AND c.id = ce.[Course ID] 
     AND c.id = cp.[Course ID] 
    WHERE EXISTS(SELECT * FROM [Course Enrolment] as ce_2 WHERE ce_2.[Person ID] = p.id and ce_2.[Course ID] = c.id) 
    AND ([date taken] < date('now', '-' || [course refresh rate] || ' year') 
    or NOT EXISTS(SELECT * FROM [Course Participation] WHERE cp.[Person ID] = p.id and cp.[Course ID] = c.id)) 
; 

Что я сделал не так?

+0

что это такое = 0? – Himanshu

+0

Непонимание инструкции Exists, я заменил ее тем, что, по моему мнению, является правильным синтаксисом. – Sam

+0

Я думаю, проблема может заключаться в том, что с вашей конструкцией 'JOIN ... ON ...' вы создаете таблицу, в которой ** ** есть только люди, у которых есть запись в ** каждой ** ваших таблиц. Попробуйте отказаться от инструкции ON в целом и затем выберите уникальные результаты. –

ответ

1
SELECT DISTINCT p.id, 
       p.[First Name], 
       p.[Last Name] 
FROM People AS p 
JOIN [Course Enrolment] AS ce ON p.id = ce.[Person ID] 
JOIN Courses AS c ON ce.[Course ID] = c.id 
LEFT JOIN [Course Participation] AS cp ON cp.[Person ID] = p.id AND 
              cp.[Course ID] = c.id 
WHERE cp.[Date Taken] IS NULL 
    OR cp.[Date Taken] < date('now', '-' || c.[Course Refresh Rate] || ' year') 
+0

Замечательно, спасибо за ответ. Все, что я должен был добавить, было точкой с запятой. – Sam

1

Как насчет фильтрации последних участников от всех других, как это: -

SELECT [First Name], 
     [Last Name] 
    FROM people AS p 
    JOIN courses AS c 
    JOIN [course enrolment] AS ce 
    ON p.id = ce.[Person ID] 
    AND c.id = ce.[Course ID] 

MINUS 

SELECT [First Name], 
     [Last Name] 
    FROM people AS p 
    JOIN courses AS c 
    JOIN [course enrolment] AS ce 
    JOIN [course participation] AS cp 
    ON p.id = ce.[Person ID] 
    AND p.id = cp.[Person ID] 
    AND c.id = ce.[Course ID] 
    AND c.id = cp.[Course ID] 
WHERE [date taken] > date('now', '-' || [course refresh rate] || ' year') 

НЕ ПРОВЕРЕНО

+0

Я согласен с логикой здесь и благодарю вас за ответ, однако при тестировании я получил ошибку. – Sam