完全外连接或右外连接

时间:2017-12-15 15:22:33

标签: sql postgresql

我有两张表格如下所示:

cat_id | cat_name
1      | free
2      | semi-paid
3      | premium
payment_id | user_id | cat_id
1          | 1       | 1
2          | 1       | 4

我想查询下面的结果

payment_id | user_id | cat_name
1          | 1       | free
null       | 1       | semi-paid
null       | 1       | premium
2          | 1       | null

如果 payment_id 为空,我将在UI-on个人资料页面上不显示付款图标。这意味着user_id = 1没有使用半付费和高级类别中的任何内容。

我试过

SELECT payment_id, user_id, cat_name 
FROM payment 
FULL JOIN category 
  ON payment.cat_id 
WHERE user_id = 1

但是我有一张笛卡尔表:(你能帮我吗?

3 个答案:

答案 0 :(得分:1)

<强> SQL DEMO

SELECT c.*, p.*, payment_id, user_id, cat_name
FROM category c
LEFT JOIN payment p
  ON c.cat_id = p.cat_id
 AND p.user_id = 1
UNION
SELECT c.*, p.*, payment_id, user_id, cat_name
FROM category c
RIGHT JOIN payment p
  ON c.cat_id = p.cat_id
 AND p.user_id = 1

OUTPUT 专注于最后3列

| cat_id |  cat_name | payment_id | user_id | cat_id | payment_id | user_id |  cat_name |
|--------|-----------|------------|---------|--------|------------|---------|-----------|
| (null) |    (null) |          2 |       1 |      4 |          2 |       1 |    (null) |
|      1 |      free |          1 |       1 |      1 |          1 |       1 |      free |
|      2 | semi-paid |     (null) |  (null) | (null) |     (null) |  (null) | semi-paid |
|      3 |   premium |     (null) |  (null) | (null) |     (null) |  (null) |   premium |

答案 1 :(得分:1)

您需要将user_id = 1置于加入条件中,否则您将过滤掉NULL行。然后,您需要NULL处理user_id

SELECT payment_id, COALESCE(user_id,1) as user_id, cat_name 
FROM payment p
FULL JOIN category c ON p.cat_id = c.cat_id 
                    AND p.user_id = 1

你也可以这样做:

SELECT payment_id, 1 as user_id, cat_name 
FROM payment p
FULL JOIN category c ON p.cat_id = c.cat_id 
                    AND p.user_id = 1

答案 2 :(得分:0)

试试这个:

 SELECT payment_id,
    case when payment_id is null 
         then 1 
         else user_id end user_Id, 
     cat_name 
    FROM payment 
    FULL outer JOIN category 
      ON payment.cat_id = category.cat_id;