单个结果的

时间:2017-09-26 18:46:47

标签: sql subquery

在我开发的大部分时间里,我一直在使用ORM工具。我需要执行一些SQL - 不在我典型的Rails环境中。

  "SELECT projects.id, projects.company_id, projects.name, 
  companies.name as company_name,
  people.name as person_name,
  users.name as user_name
  FROM projects
  INNER JOIN companies ON companies.id = projects.company_id
  LEFT OUTER JOIN project_people ON project_people.project_id = projects.id
  LEFT OUTER JOIN people ON people.id = project_people.person_id
  LEFT OUTER JOIN project_users ON project_users.project_id = projects.id
  LEFT OUTER JOIN users ON users.id = project_users.user_id"

如果我选择单个记录,我通常会在结果中获得多行,例如如果我有2个project_people和2个project_users。

我会得到:

  {"id"=>"7744", "company_id"=>"42598", "name"=>"Project with a name", "company_name"=>"(Confidential)", "person_name"=>"A person name", "user_name"=>nil} 
  {"id"=>"7744", "company_id"=>"42598", "name"=>"Project with a name", "company_name"=>"(Confidential)", "person_name"=>"Another name", "user_name"=>nil}
  {"id"=>"7744", "company_id"=>"42598", "name"=>"Project with a name", "company_name"=>"(Confidential)", "person_name"=>"Another name", "user_name"=>'Some user'}
  {"id"=>"7744", "company_id"=>"42598", "name"=>"Project with a name", "company_name"=>"(Confidential)", "person_name"=>"A person name", "user_name"=>'Some user'}

我想要的是以下:

  {"id"=>"7744", "company_id"=>"42598", "name"=>"Project with a name", "company_name"=>"(Confidential)", "people"=>{
              "person_name"=>"A person name",
              "person_name"=>"Another name",
        }, "users"=>{
              "user_name"=>nil, 
              "user_name"=>'Some user'
        }
  }

我知道你们中的一些大师在SQL中你可以很容易地解决这个问题,但我还是觉得这对我这么蹩脚的问题是多么可怕。我确信这是可能的 - 只需一个查询

1 个答案:

答案 0 :(得分:0)

我在postgres中偶然发现了这个array_agg - 似乎做了我需要的事情!

 "SELECT projects.id, projects.company_id, projects.name, 
  companies.name AS company_name,
  array_agg(people.name) AS people,
  array_agg(users.name) AS users
  FROM projects
  INNER JOIN companies ON companies.id = projects.company_id
  LEFT OUTER JOIN project_people ON project_people.project_id = projects.id
  LEFT OUTER JOIN people ON people.id = project_people.person_id
  LEFT OUTER JOIN project_users ON project_users.project_id = projects.id
  LEFT OUTER JOIN users ON users.id = project_users.user_id
  GROUP BY projects.id"

我也发现这个删除重复;-) - 我不知道这是如何表现的,但是它能很好地完成工作

  array_agg(DISTINCT CONCAT(people.id, ' ', people.name)) AS people
  array_agg(DISTINCT CONCAT(users.id, ' ', users.name)) AS users