30 марта 2020 г. Gorm Sql Postgresql
Эта задача не так проста, особенно с GORM.
Рассмотрим следующие сущности:
type Parent struct {
gorm.Model
Name string
}
type Child struct {
gorm.Model
ParentID uint // связь child -> parent многие к одному
Name string
}
Как отфильтровать родителей, фильтруя связанных детей?
Общее решение в SQL-базах данных — использовать простой JOIN и затем фильтровать. Это возможно с GORM:
err := db.Model(&Parent{}).Joins(
"LEFT JOIN children ON parents.id = children.parent_id AND children.name = ?",
"somename",
).Find(&results).Error
Полный запрос:
SELECT * FROM "parents" LEFT JOIN children ON parents.id = children.parent_id AND children.name = 'somename'
Но это обычно не работает для нашей задачи — для родителей, у которых есть несколько подходящих детей. В этом случае такие родители будут повторяться несколько раз.
Таким образом, простой JOIN здесь, вероятно, не работает. Нам, вероятно, нужно решение на основе условия WHERE. Следующий код работает отлично:
err := db.Model(&Parent{}).Where(
"EXISTS (SELECT 1 FROM children WHERE children.parent_id = parents.id AND children.name = ?)",
"somename",
).Find(&results).Error
Полный запрос выглядит следующим образом:
SELECT * FROM "parents" WHERE EXISTS (SELECT 1 FROM children WHERE children.parent_id = parents.id AND children.name = 'somename')