如果未找到行,则SQL返回默认值[PostgreSQL]

3
我在想是否可以(如果可能的话,只使用一个查询)使查询返回默认值,如果行缺失?例如,考虑这两个表格,给定我的查询需要2个参数(place_id和user_id)。
T1
place_id / tag_id
1            2
1            3
1            4
2            4
3            2
4            5

T2
user_id / tag_id / count
100         2        1
100         3        20
200         4        30
200         2         2
300         5        22

如您所见,用户/标签(100,4)对缺失。我想要实现的是一条查询语句,能够返回这三个结果。

tag_id / count
2           1
3           20
4           0

我知道可以使用类似以下代码的方法实现,但这并不符合最终结果,因为它只在我预先知道 tag_id 时有效,并且只返回一行结果:

SELECT T1.tag_id, T2.count 
from T1 t1 
    left join T2 t2 on t1.tagId=t2.tag_id 
where t1.place_id=1 
UNION ALL 
select tag_id,0 
from T1 
where not exist (select 1 from T2 where user_id=100 and tag_id=4) 
  and tag_id=4;
编辑:我的问题不完整,还有一些案例遗漏了。这是一个例子(感谢@a_horse_with_no_name):http://sqlfiddle.com/#!12/67042/4

谢谢!


1
具有 tag_id = 4 的行将被外连接返回。您只需要使用 coalesce()null 值转换为 0 即可。请参见此处的示例:http://sqlfiddle.com/#!12/ed7bf/1 - user330315
@a_horse_with_no_name 我们能否在非外键/主键列上连接表格? - user3522371
您可以在具有匹配数据类型的任何列上连接表格。 - user330315
@a_horse_with_no_name 谢谢!我觉得这个可以解决问题!(顺便说一下,我还需要添加 "and t2.user_id=100";因为在 T2 中也可能有类似这样的情况(200,4,50)(另一个用户链接到标签 4)。 - Johny19
1个回答

1

外连接已经可以满足你的需求。

由于t1是连接中的“左表”,所有来自t1的行都将被返回。然后,“右表”(例如你的例子中的t2)的列将具有null值。因此,您只需要将该null转换为0

select t1.tag_id, coalesce(t2.cnt, 0)
from T1 t1 
    left join T2 t2 on t1.tag_Id=t2.tag_id 
and t1.place_id = 1;

SQLFiddle 示例:http://sqlfiddle.com/#!12/ed7bf/1


无关但:

使用count作为列名是一个非常糟糕的想法,因为它将要求您始终将列名括在双引号中:t2."count",因为它是保留字。此外,它并没有真正记录列的用途。您应该找到更好的名称。


关于列名,我问题中的表是临时创建并输入的。我一直在尝试在我的表上运行此查询,并意识到它并没有完全返回我想要的结果。请看这个例子:http://sqlfiddle.com/#!12/67042/4(我已添加其他标签和用户) - Johny19
@Johny19:请编辑您的问题,并根据您的SQLFiddle包括预期输出(在问题中包括SQLFiddle的链接)。 - user330315

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接