У меня есть приложение базы данных django, которое постоянно развивается.
Мы хотим отслеживать ход сэмплов по мере их продвижения от
sample -> library -> machine -> statistics, etc.
Как правило, это отношение один ко многим на каждом этапе слева направо.
Вот упрощенная версия схемы моей базы данных
table sample
id
name
table library
id
name
sample_id (foreign key to sample table)
table machine
id
name
status
library_id (foreign key to library table)
table sample_to_projects
sample_id
project_id
table library_to_subprojects
library_id
subproject_id
Пока все шло нормально, за исключением того, что все должно просматриваться проектами.Каждый из этапов может принадлежать одному или нескольким проектам.Я добавил отношение many_to_many между проектом и существующими таблицами.
Я пытаюсь создать несколько представлений, которые выполняют несколько левых объединений и показывают ход выполнения образцов для проекта.
sample A
sample B library_1 machine_1
sample B library_2 machine_2
sample C library_3
Первая попытка запроса была такой:
SELECT fields FROM
sample_to_projects ,
sample
LEFT JOIN library ON sample.id = library.sample_id ,
library_to_project
LEFT JOIN machine ON machine.library_id = library.id
WHERE
sample_to_project.project_id = 30
AND sample_to_project.sample_id = sample.id
AND library_to_project.project_id = 30
AND library_to_project.library_id = library_id
Проблема в том, что LEFT JOIN выполняется перед предложением WHERE.
Так что, если у нас есть пример, который принадлежит project_A и project_B.Если в примере есть библиотека для project_B, но мы хотим выполнить фильтрацию для project_A, LEFT JOIN не добавляет строку со значениями NULL для библиотечных столбцов (так как есть библиотеки).Однако эти строки отфильтровываются обратно предложением WHERE, и образец не отображается.
reults filtering on project_A
sample_1(project_A, project_B) library_A (project_A)
sample_1(project_A, project_B) library_B (project_A, project_B)
sample_2(project_A, project_B) library_C (project_B) *this row gets filtered out, it should show only the sample details*
Итак, мое решение - создать подзапрос для объединения других (правых) таблиц до того, как будет выполнено LEFT JOIN.
SELECT fields FROM
sample_to_projects ,
sample
LEFT JOIN (
SELECT library.id as lib_id , library.sample_id as smaple_id , library.name as lib_name , machine_name
FROM library ,
lib_to_projects ,
machine
)
AS join_table ON sample.id = join_table.sample_id
WHERE
sample_to_project.project_id = 30
AND sample_to_project.sample_id = sample.id
Проблема в том, что в реальной версии моей базы данных есть еще несколько этапов, поэтому мне нужно будет делать вложенный подзапрос для каждого LEFT JOIN.SQL будет получать довольно большие рекламные материалы, трудные для чтения, и я подумал, есть ли лучшее решение на уровне дизайна?Также он не будет хорошо работать с моделями Django (хотя, если я смогу заставить работать SQL, я буду достаточно счастлив).
Или кто-нибудь может порекомендовать какую-нибудь лучшую практику для этого типа проблемы?Я уверен, что это должно быть относительно распространенным показом пользователей в группах или чем-то подобным.Если кто-нибудь знает способ, который хорошо подошел бы к моделям Django, это было бы еще лучше.