mysql - mysql中如何从一对多关系的两个表中获取数据?

标签 mysql join go inner-join

我有两个结构:

type User struct {
    Id uint32
    First string
    Last string
    Adds []Address
}

type Address struct {
    Id uint32
    Location string
}

我有两个表:

create table user (
    Id INT UNSIGNED NOT NULL AUTO_INCREMENT,
    First VARCHAR(40) NULL,
    Last VARCHAR(40) NULL,
    PRIMARY KEY (Id)
);

create table address (
    Id INT UNSIGNED NOT NULL AUTO_INCREMENT,
    UserId INT UNSIGNED NOT NULL,
    Location VARCHAR(400) NOT NULL,
    FOREIGN KEY (UserId) REFERENCES user (Id),
    PRIMARY KEY (Id)
);

"address" 表与"user" 表有一对多关系。 那么如何使用inner join 从这两个表中获取数据并将其保存在"user"struct instance 中?

注意:没有gorm或其他orm库?

最佳答案

使用单个查询和 JOIN:

func GetUser(db *sql.DB, id int) (*User, error) {    
    rows, err := db.Query(`
        SELECT
            User.Id AS UserId,
            User.First AS UserFirst,
            User.Last AS UserLast,
            Location.Id AS LocationId,
            Location.Location AS LocationLocation
        FROM User
        LEFT JOIN Location ON
            User.Id = Location.UserId
        WHERE User.Id = ?
    `, id)
    if err != nil {
        return nil, err
    }
    defer rows.Close()

    var u *User
    for rows.Next() {
        if u == nil {
            u = new(User)
        }
        var locationID sql.NullInt64
        var location sql.NullString
        err := rows.Scan(
            &u.Id,
            &u.First,
            &u.Last,
            &locationID,
            &location,
        )
        if err != nil {
            return nil, err
        }
        if locationID.Valid && location.Valid {
            u.Adds = append(u.Adds, Address{
                Id:       uint32(locationID.Int64),
                Location: location.String,
            })
        }
    }

    if err := rows.Err(); err != nil {
        return nil, err
    }

    return u, nil
}

或者,您可以使用两个查询,我认为这更简洁:

func GetUser(db *sql.DB, id int) (*User, error) {
    u := new(User)
    err := db.QueryRow(`
        SELECT
            Id,
            First,
            Last
        FROM
            user
        WHERE Id = ?   
    `, id).Scan(
        &u.Id,
        &u.First,
        &u.Last,
    )
    if err != nil {
        if err == sql.ErrNoRows {
            return nil, nil
        }
        return nil, err
    }

    rows, err := db.Query(`
        SELECT
            Id,
            Location
        FROM
            addresses
        WHERE UserId = ?
    `, id)
    if err != nil {
        return nil, err
    }
    defer rows.Close()
    for rows.Next() {
        var address Address
        err := rows.Scan(
            &address.Id,
            &address.Location,
        )
        if err != nil {
            return nil, err
        }
        u.Adds = append(u.Adds, address)
    }

    if err := rows.Err(); err != nil {
        return nil, err
    }

    return u, nil
}

关于mysql - mysql中如何从一对多关系的两个表中获取数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48448555/

相关文章:

mysql - 更新正则表达式 MYSQL

mysql - 如何使用 Spring Boot 回滚 MySQL 数据库中的所有更改

php - 唯一、不可预测、12 位数字、整数 id

mysql - 我无法更改数据库列

php - 将一个mysql表中的一行连接到第二个表中的多行

mysql - 使用 group by 或 distinct 删除重复项

gometalinter 将输出保存到 xml

http - 我可以发布 Content-Type : multipart/form-data 吗

go - 如何避免发送 Content-Length header

javascript - 弹出消息无法显示来自 php mysql 的新更新记录