duanshaiduhao2471 2019-03-13 21:01
浏览 45
已采纳

如何合并相关数据

I need some theoretical/practical help in code organization.

I have such table in PostgreSQL database. The table shows the relationship between organizations.

| ORGANIZATION_ID | ORGANIZATION_NAME | PARENT_ORGANIZATION_ID | ORGANIZATION_RANG | TREE_ORGANIZATION_ID | TREE_ORGANIZATION_ NAME |
|-----------------|-------------------|------------------------|-------------------|----------------------|-------------------------|
| 1               | Google            |                        | 1                 | \1                   | \Google                 |
| 2               | Nest              | 1                      | 2                 | \1\2                 | \Google\Nest            |
| 3               | Verily            | 1                      | 2                 | \1\3                 | \Google\Verily          |
| 4               | Calico            |                        | 1                 | \4                   | \Calico                 |
| 5               | ATAP              | 4                      | 2                 | \4\5                 | \Calico\ATAP            |

In my Go application I create struct for this table then make SQL query.

type Organization struct {
    ID int `json:"organization_id"`
    Name string `json:"organization_name"`
    Rang int `json:"organization_rang"`
    Children []Organization `json:"children"`
}

var GetOrganizations = func(responseWriter http.ResponseWriter, request *http.Request) {
    rows,err := db.Query("select * from ORG")
    if err != nil {
        fmt.Println(err)
        return
    }

    defer rows.Close()

    var organizations []Organization

    for rows.Next() {
        var organization Organization

        err = rows.Scan(&organization.ID, &organization.Name, &organization.Rang)
        if err != nil {
            fmt.Println(err)
            return
        }

        organizations = append(organizations, organization)
    }

    utils.Response(responseWriter, http.StatusOK, organizations)
}

I need to make such response. What would you advise to reorganize in my current code?

[
    {
        "organization_id": 1,
        "organization_name": "Google",
        "organization_rang": 1,
        "children": [
            {
                "organization_id": 2,
                "organization_name": "Nest",
                "organization_rang": 2,
                "children": null
            },
            {
                "organization_id": 3,
                "organization_name": "Verily",
                "organization_rang": 2,
                "children": null
            }
        ]
    },
    {
        "organization_id": 4,
        "organization_name": "Calico",
        "organization_rang": 1,
        "children": [
            {
                "organization_id": 2,
                "organization_name": "Nest",
                "organization_rang": 2,
                "children": null
            }
        ]
    }
]

EDIT:

@antham for example I add new record called Telsa. As you can see it's parent is Nest object.

| ORGANIZATION_ID | ORGANIZATION_NAME | PARENT_ORGANIZATION_ID | ORGANIZATION_RANG | TREE_ORGANIZATION_ID | TREE_ORGANIZATION_ NAME |
|-----------------|-------------------|------------------------|-------------------|----------------------|-------------------------|
| 1               | Google            |                        | 1                 | \1                   | \Google                 |
| 2               | Nest              | 1                      | 2                 | \1\2                 | \Google\Nest            |
| 3               | Verily            | 1                      | 2                 | \1\3                 | \Google\Verily          |
| 4               | Calico            |                        | 1                 | \4                   | \Calico                 |
| 5               | ATAP              | 4                      | 2                 | \4\5                 | \Calico\ATAP            |
| 6               | Tesla             | 2                      | 3                 | \1\2\6               | \Google\Nest\Tesla      |

Result of your code:

[
    {
        "organization_id": 1,
        "organization_name": "Google",
        "organization_rang": 1,
        "children": [
            {
                "organization_id": 3,
                "organization_name": "Verily",
                "organization_rang": 2,
                "children": null
            },
            {
                "organization_id": 2,
                "organization_name": "Nest",
                "organization_rang": 2,
                "children": [
                    {
                        "organization_id": 6,
                        "organization_name": "Tesla",
                        "organization_rang": 3,
                        "children": null
                    }
                ]
            }
        ]
    },
    {
        "organization_id": 2,
        "organization_name": "Nest",
        "organization_rang": 2,
        "children": [
            {
                "organization_id": 6,
                "organization_name": "Tesla",
                "organization_rang": 3,
                "children": null
            }
        ]
    },
    {
        "organization_id": 4,
        "organization_name": "Calico",
        "organization_rang": 1,
        "children": [
            {
                "organization_id": 5,
                "organization_name": "ATAP",
                "organization_rang": 2,
                "children": null
            }
        ]
    }
]
  • 写回答

1条回答 默认 最新

  • dongxian4531 2019-03-14 23:06
    关注

    If I understand properly what you want to do, here you have an unoptimized example, it's done with sqlite but it will work the same with postgres :

    package main
    
    import (
        "database/sql"
        "encoding/json"
        "fmt"
        "log"
        "sort"
    
        _ "github.com/mattn/go-sqlite3"
    )
    
    type Organization struct {
        ID       int             `json:"organization_id"`
        Name     string          `json:"organization_name"`
        Rang     int             `json:"organization_rang"`
        Children []*Organization `json:"children"`
    }
    
    func main() {
        db, err := sql.Open("sqlite3", "./database")
        if err != nil {
            log.Fatal(err)
        }
    
        defer db.Close()
    
        rows, err := db.Query("select ORGANIZATION_ID,ORGANIZATION_NAME,ORGANIZATION_RANG,PARENT_ORGANIZATION_ID from ORG")
        if err != nil {
            log.Fatal(err)
        }
    
        defer rows.Close()
    
        orgs := map[int]*Organization{}
    
        for rows.Next() {
            organization := &Organization{}
            var parentID sql.NullInt64
    
            if err = rows.Scan(&organization.ID, &organization.Name, &organization.Rang, &parentID); err != nil {
                log.Fatal(err)
            }
    
            if parentID.Valid {
                if parentOrg, ok := orgs[int(parentID.Int64)]; ok {
                    parentOrg.Children = append(parentOrg.Children, organization)
                } else {
                    orgs[int(parentID.Int64)] = &Organization{ID: int(parentID.Int64)}
                    orgs[int(parentID.Int64)].Children = append(orgs[int(parentID.Int64)].Children, organization)
                }
            }
    
            if _, ok := orgs[organization.ID]; ok {
                orgs[organization.ID].Name = organization.Name
                orgs[organization.ID].Rang = organization.Rang
                continue
            }
    
            orgs[organization.ID] = organization
        }
    
        IDs := []int{}
        for k := range orgs {
            IDs = append(IDs, k)
        }
        sort.Ints(IDs)
    
        organizations := []Organization{}
        for _, ID := range IDs {
            if len(orgs[ID].Children) > 0 && orgs[ID].Rang == 1 {
                organizations = append(organizations, *orgs[ID])
            }
        }
    
        content, err := json.MarshalIndent(organizations, "", "  ")
        if err != nil {
            log.Fatal(err)
        }
    
        fmt.Println(string(content))
    }
    

    I get this :

    [
      {
        "organization_id": 1,
        "organization_name": "Google",
        "organization_rang": 1,
        "children": [
          {
            "organization_id": 2,
            "organization_name": "Nest",
            "organization_rang": 2,
            "children": null
          },
          {
            "organization_id": 3,
            "organization_name": "Verily",
            "organization_rang": 2,
            "children": null
          }
        ]
      },
      {
        "organization_id": 4,
        "organization_name": "Calico",
        "organization_rang": 1,
        "children": [
          {
            "organization_id": 5,
            "organization_name": "ATAP",
            "organization_rang": 2,
            "children": null
          }
        ]
      }
    ]
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 identifier of an instance of 类 was altered from xx to xx错误
  • ¥100 反编译微信小游戏求指导
  • ¥15 docker模式webrtc-streamer 无法播放公网rtsp
  • ¥15 学不会递归,理解不了汉诺塔参数变化
  • ¥30 软件自定义无线电该怎样使用
  • ¥15 R语言mediation包做中介分析,直接效应和间接效应都很小,为什么?
  • ¥15 Jenkins+k8s部署slave节点offline
  • ¥15 如何实现从tello无人机上获取实时传输的视频流,然后将获取的视频通过yolov5进行检测
  • ¥15 WPF使用Canvas绘制矢量图问题
  • ¥15 用三极管设计一个单管共射放大电路