чувство рождаемости: использование объединений в горм - PullRequest
0 голосов
/ 05 сентября 2018

Отказ от ответственности: я впервые использую 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-запрос?

Ответы [ 2 ]

0 голосов
/ 23 октября 2018

Этот запрос, вероятно, также будет работать. Я надеюсь, что это полезно.

if err := db.Table("listens").Select("songs.id, listens.count").
Joins("JOIN songs on listens.song_id = songs.id").Where("user_id = ?", 
1).Find(&rs).Error; err != nil {
    fmt.Prinln(err)
}
0 голосов
/ 06 сентября 2018

В итоге я нашел, как это сделать:

db.Table("songs"). Select("songs.id, listens.count"). Joins("left join (select * from listens where user_id = ?) as listens on songs.id = listens.song_id", 1). Find(&rs)

...