左连接如何与sqlx一起工作

kpbpu008  于 2021-06-20  发布在  Mysql
关注(0)|答案(3)|浏览(460)

我在试着把两张table连起来 person 以及 profile 使用一个简单的查询,它似乎可以很好地处理mysql,但不能处理sqlx。这是我的密码:

package main 

import (
    "fmt"
    "github.com/jmoiron/sqlx"
    _ "github.com/go-sql-driver/mysql"
)

type Person struct {
    Id      int64   `db:"id"`
    Name    string  `db:"name"`
    Email   string  `db:"email"`
}

type Profile struct {
    Id          int64   `db:"id"`
    Face        string  `db:"face"`
    Hair        string  `db:"hair"`
    Person
}

func main() {
    DB, err := sqlx.Connect("mysql", "root:hackinitiator@/dusk")
    if err == nil {
        fmt.Println("sucess!!")
    } 
    var q []Profile
    DB.Select(&q, "select person.id, person.name, person.email, profile.id, profile.face, profile.hair from profile left join person on person.id = profile.person_id")
    fmt.Println(q)
}

mysql查询生成以下输出:

+------+------+---------+----+----------+--------+
| id   | name | email   | id | face     | hair   |
+------+------+---------+----+----------+--------+
|    1 | yoda | nomail  |  1 | round    | brown  |
|    5 | han  | nomail1 |  3 | circle   | red    |
|    6 | yun  | nomail2 |  4 | triangle | yellow |
|    7 | chi  | nomail3 |  5 | square   | green  |
+------+------+---------+----+----------+--------+

这很好,但我的围棋程序没有按预期React。结构无法捕获配置文件id(输出中为空),人员id被替换为配置文件id。下面是输出(格式化):

[
{0 round brown {1 yoda nomail}} 
{0 circle red {3 han nomail1}} 
{0 triangle yellow {4 yun nomail2}} 
{0 square green {5 chi nomail3}}
]

我不知道出了什么问题。

nxagd54h

nxagd54h1#

你需要改变 db 姓名 person 我在描述下面这样的结构,因为会有两个同名的列。 id 所以它只扫描你的 profile 表和不扫描 person 表,所以按照下面提到的结构。

type Person struct {
    Id      int64   `db:"pId"`
    Name    string  `db:"name"`
    Email   string  `db:"email"`
}

然后用 as 为了 person.id 喜欢

DB.Select(&q, "select (person.id) as pId, person.name, person.email, profile.id, profile.face, profile.hair from profile left join person on person.id = profile.person_id")
vktxenjb

vktxenjb2#

错误是由于返回两个 id 列,但将结果存储在两个结构中具有相同字段名id的结构中,您要将其示例传递给db.select。尝试捕获单个id列并将其传递给struct。
传递多个列,但不同的列名称可以用作别名。列别名将是person结构中的字段,您将在其中扫描数据:

type Person struct {
    PersonId    int64   `db:"personId"`
    Name        string  `db:"name"`
    Email       string  `db:"email"`
}

var q []Profile
DB.Select(&q, "select person.id as personId, person.name, person.email, profile.id, profile.face, profile.hair from profile left join person on person.id = profile.person_id")
fmt.Println(q)
uhry853o

uhry853o3#

在@zerkms提供的代码片段之后,我做了一些更改,使我可以运行程序而不会出错,也不会重命名db标记。首先,我在profile struct中添加了下面的代码,以便查询识别person struct

Person `db:"person"`

在此之后,我将sql查询字符串更改为以下代码

DB.Select(&q, `select person.id "person.id", person.name "person.name", person.email "person.email", profile.* from profile left join person on person.id = profile.person_id`)

避免@zerkms指出的重复列名

相关问题