Отказ от ответственности: я впервые использую ORM, и мой SQL может быть немного ржавым.
У меня есть приложение с пользователями, песнями, и я хочу посчитать и отобразить, сколько раз каждая песня была воспроизведена данным пользователем. Я знаю, как сделать это с SQL, но мне не удается перевести это в GORM. Это выглядит так:
package main
import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/sqlite"
)
type User struct {
ID int `gorm:"primary_key"`
Listened []Listen
}
type Song struct {
ID int `gorm:"primary_key"`
Title string
Listened []Listen
}
type Listen struct {
UserID int `gorm:"primary_key;auto_increment:false"`
SongID int `gorm:"primary_key;auto_increment:false"`
Count int
}
Тогда давайте добавим некоторые данные
func main() {
db, err := gorm.Open("sqlite3", "test.db")
if err != nil {
panic(err)
}
defer db.Close()
db.DropTableIfExists(&User{}, &Song{}, &Listen{})
db.CreateTable(&User{}, &Song{}, &Listen{})
db.Save(&User{ID: 1})
db.Save(&User{ID: 2})
db.Save(&Song{ID: 1, Title: "oh yeah"})
db.Save(&Song{ID: 2, Title: "greatest song"})
db.Save(&Song{ID: 3, Title: "bestest song"})
db.Save(&Listen{UserID: 1, SongID: 1, Count: 7})
db.Save(&Listen{UserID: 1, SongID: 2, Count: 23})
db.Save(&Listen{UserID: 2, SongID: 2, Count: 13})
db.Save(&Listen{UserID: 2, SongID: 3, Count: 10})
// do something here
}
Теперь, как я уже сказал, я хочу перечислить, сколько раз пользователь проигрывал каждую песню в базе данных. Немного почесав голову, я пришел к этому:
sqlite> select songs.id, l.count from songs
...> left join (select song_id, count from listens where user_id = 1) as l
...> on songs.id = l.song_id;
id count
---------- ----------
1 7
2 23
3
... и вот я здесь. Я просто не понимаю, как я могу выразить это с помощью цепочек методов GORM. Или я должен просто сдаться и запустить необработанный SQL-запрос?