PostgreSQL数据库有两个表:user_properties和properties。属性表包含具有ID(字典)的所有可能属性的列表。 user_properties表包含用户拥有的属性,并从属性表中引用属性ID。
属性表:
----------------------
prop_id | prop_name
----------------------
1 | Email
----------------------
2 | Phone number
----------------------
3 | Something else 1
----------------------
4 | Something else 2
----------------------
user_properties表:
--------------------------------
user_id | prop_id | prop_value
--------------------------------
100 | 1 | asd@zxc.com
--------------------------------
100 | 2 | 1234567
--------------------------------
100 | 2 | 2345678
--------------------------------
101 | 3 | *******
--------------------------------
101 | 3 | +++++++
--------------------------------
我需要知道每个user_id缺少哪些属性。 预期结果应类似于:
-----------------------
user_id | missing_prop_id
-----------------------
100 | 3
-----------------------
100 | 4
-----------------------
101 | 1
-----------------------
101 | 2
-----------------------
101 | 4
-----------------------
答案 0 :(得分:0)
您可以将except
用作:
with properties(prop_id,prop_name) as
(
values(1, 'Email'),(2, 'Phone number'),
(3, 'Something else 1'),(4, 'Something else 2')
), user_properties( user_id, prop_id, prop_value) as
(
values(100,1,'asd@zxc.com'),(100,2,'1234567'),(100,2,'2345678'),
(101,3,'*******'),(101,3,'+++++++')
), t2 as
(
select u.user_id, p.prop_id as missing_prop_id
from user_properties u
cross join properties p
group by u.user_id, p.prop_id
except
select u.user_id,
p.prop_id
from user_properties u
right join properties p
on u.prop_id = p.prop_id
group by u.user_id, p.prop_id
)
select * from t2 order by user_id, missing_prop_id;
user_id missing_prop_id
100 3
100 4
101 1
101 2
101 4
答案 1 :(得分:0)
您可以简单地通过加入来解决此问题...
SELECT DISTINCT t3.user_id, t3.prop_id FROM
(SELECT DISTINCT user_id, t2.prop_id FROM user_properties t1, properties t2) t3
LEFT JOIN user_properties t4 ON t3.user_id = t4.user_id and t3.prop_id = t4.prop_id WHERE t4.prop_id is null
答案 2 :(得分:0)
您可以使用cross join
生成所有行,并使用left join
过滤掉不存在的行:
select u.user_id, p.prop_id
from (select distinct user_id from user_properties
) u cross join
properties p left join
user_properties up
on up.user_id = u.user_id and
up.prop_id = p.prop_id
where up.user_id is null;
大概您有一个users
表,因此不需要u
的子查询:
select u.user_id, p.prop_id
from users u cross join
properties p left join
user_properties up
on up.user_id = u.user_id and
up.prop_id = p.prop_id
where up.user_id is null;
答案 3 :(得分:0)
感谢大家的帮助。我本人想出了以下查询:
select mp.user_id, mp.prop_id missing_prop_id from
(select distinct up.user_id, p.prop_id from user_properties up cross join properties p) mp
except
select distinct user_id, prop_id from user_properties