如何进行JOIN查询而不忽略具有NULL值的记录?

时间:2018-01-15 08:47:54

标签: sql ruby-on-rails ruby postgresql join

我的Postgres数据库中有3个表:

用户

 Column |         Type          
--------+-----------------------
 id     | integer               
 name   | character varying(50)

产品

   Column    |         Type          
-------------+-----------------------
 id          | integer               
 name        | character varying(50) 
 user_id     | integer               
 category_id | integer 

类别

 Column |         Type          
--------+-----------------------
 id     | integer               
 name   | character varying(50)

用户中的示例数据

id | name
---+------
1  | John
2  | Sara

产品中的示例数据

id | name           | user_id | category_id
---+----------------+---------+------------
1  | iPhone 8       | 1       | 1
2  | MacBook        | 1       | 2
3  | Fidget Spinner | 1       | NULL
4  | Dell XPS       | 1       | 2
5  | Samsung S8     | 2       | 1

类别中的示例数据

id | name
---+-----------
1  | Mobile Phones
2  | Laptops
3  | Toys

我的Rails项目中有一条路线,我希望此路线的操作返回如下结果:

[
   {
      "category":"Mobile Phones",
      "products":[
         {
            "id":1,
            "name":"iPhone 8"
         }
      ]
   },
   {
      "category":"Laptops",
      "products":[
         {
            "id":2,
            "name":"MacBook"
         },
         {
            "id":4,
            "name":"Dell XPS"
         }
      ]
   },
   {
      "category":"Toys",
      "products":[

      ]
   }
]

基本上,当John称这个端点时,他会看到他所有的产品。最重要的是,我想展示所有类别,无论他们是否有产品。

请为此提供最好,最有效的Rails ActiveRecord或SQL语句。

3 个答案:

答案 0 :(得分:1)

使用左外连接。它还将返回空值 -

例如,对于表t1和表t2 -

  SELECT *
FROM table1 t1 LEFT OUTER JOIN table2 t2
   ON t1.a = t2.c
ORDER BY t1.a

答案 1 :(得分:1)

将用户的产品加入到类别中以获取所有类别:

select
  c.name as category_name,
  p.id as product_id,
  p.name as product_name
from categories c
left join products p on p.category_id = c.id and p.user_id = 1;

答案 2 :(得分:0)

如果您想获取主/查找表中不存在的记录,那么您可以使用左/右连接

SELECT *
FROM products AS p
LEFT JOIN users AS u ON u.id = p.user_id
LEFT JOIN categories AS c ON c.id = p.category_id