#sql #postgresql #knex.js
#sql #postgresql #knex.js
Вопрос:
У меня есть шесть таблиц, которые мне нужно объединить и вернуть большой фрагмент данных из PostgreSQL и Knex.js , или необработанный запрос, если Knex его не поддерживает. Учетные записи, учащиеся, когорты, типы когорт, навыки, навыки учащихся.
Я могу объединить учетные записи с типами когорт без проблем, чтобы вернуть каждому учащемуся соответствующую информацию об учетной записи, профиле учащегося и типе когорты / когорты.
Проблема заключается в попытке добавить навыки / навыки учащихся, потому что каждая строка может иметь несколько навыков. Эти навыки формируются в трех таблицах.
Навыки: ID PK, умение
Skill_type: идентификатор PK, skill_id FK, тип
Student_Skills: ID PK, Student_ID FK, Skill_ID FK
Для целей этого запроса тип навыка не имеет значения. Мне нужно вернуть имя навыка для каждого навыка ученика, а не идентификатор навыка.
Каждый возвращенный студент может обладать несколькими навыками, и именно здесь я сталкиваюсь со своей проблемой. По сути, мне нужно сформировать массив в каждой строке возвращаемого значения со столбцом Skills, который содержит все навыки для этого идентификатора студента. Пример:
"id": 1,
"profile_pic": null,
"location": "somewhere",
"relocatable": true,
"website": "some-site",
"github": null,
"linkedin": "linkedin",
"twitter": "twitter",
"first_name": "name",
"last_name": "last",
"cohort_name": null,
"track": null,
"skills": [
"HTML",
"CSS",
"SASS"
]
Способ, которым я в настоящее время успешно это сделал, — получить всех учащихся без навыков, а затем выполнить индивидуальный запрос для каждого учащегося, чтобы получить и изменить их навыки.
Я чувствую, что это, вероятно, очень неэффективно и очень дорого для больших наборов данных.
В качестве альтернативы, я мог бы получить все навыки учащихся и перебирать каждый из массивов, сопоставляя навыки, которым соответствует идентификатор студента. Я тоже не уверен, что это правильный путь.
Мой текущий рабочий код:
cards = await db("students")
.select(
"students.id",
"students.profile_pic",
"students.location",
"students.relocatable",
"students.website",
"students.github",
"students.linkedin",
"students.twitter",
"students.careers_approved",
"accounts.first_name",
"accounts.last_name",
"cohorts.cohort_name",
"cohort_types.type as track"
)
.innerJoin("accounts", "accounts.id", "students.account_id")
.leftOuterJoin("cohorts", "students.cohort_id", "cohorts.id")
.leftOuterJoin(
"cohort_types",
"cohorts.cohort_type_id",
"cohort_types.id"
);
cards = bluebird.map(cards, async card => {
skills = await db("student_skills")
.select("skills.skill")
.innerJoin("skills", "skills.id", "student_skills.skill_id")
.where({ "student_skills.student_id": card.id });
return {
...card,
skills: skills.map(skill => skill.skill)
};
});
Есть ли какие-либо эксперты по SQL, которые могли бы помочь мне правильно справиться с этим?