postgres-如果不存在具有所提供用户标识的行,则选择用户标识为null的项

roejwanj  于 2021-07-24  发布在  Java
关注(0)|答案(3)|浏览(281)

我有一张table item_metadata(item_id, item_name, user_id) .
我在储存同样的东西 item_id 具有自定义名称,具体取决于 user_id ,如果没有自定义名称可用,我希望使用“默认”名称。

item_id | item_name       | user_id
001     | 'Default Name'  | NULL
001     | 'Custom Name'   | 100

鉴于上述情况,我希望返回我的查询 'Custom Name' 如果我过去 100 作为 user_id 参数,但返回 'Default Name' 如果我过去 101 作为 user_id 参数。
我试过用 COALESCE , UNION / INTERSECT / EXCEPT 但我似乎没有得到我想要的结果。

5uzkadbs

5uzkadbs1#

我知道这会让你的问题变得复杂,所以如果这不符合你的情况,那么请在评论中这样说,我会删除它。
我遇到过这样的情况:一个项目有一个默认名称,但我们希望为特定用户显示一个自定义名称。
模型如下:
架构(postgresql v11)

create table item (
  id int primary key,
  default_name text
);

create table user_tab (
  id int primary key,
  user_name text
);

create table item_user_name_override (
  item_id int references item(id),
  user_id int references user_tab(id),
  custom_name text
);

insert into user_tab values (1, 'special_user'), (2, 'regular_guy');
insert into item values (1, 'Item 1'), (2, 'Item 2'), (3, 'Item 3');
insert into item_user_name_override values (1, 1, 'Special Name for Item 1');

提取所有用户/项目对

select u.user_name, i.id as item_id, 
       coalesce(no.custom_name, i.default_name) as item_name
  from user_tab u
 cross join item i
  left join item_user_name_override no 
   on no.item_id = i.id and no.user_id = u.id
 order by i.id, u.id 
;
| user_name    | item_id | item_name               |
| ------------ | ------- | ----------------------- |
| special_user | 1       | Special Name for Item 1 |
| regular_guy  | 1       | Item 1                  |
| special_user | 2       | Item 2                  |
| regular_guy  | 2       | Item 2                  |
| special_user | 3       | Item 3                  |
| regular_guy  | 3       | Item 3                  |

db fiddle视图

fwzugrvs

fwzugrvs2#

你可以用它 coalesce() 这样地:

select coalesce(
  (select item_name from item_metadata where user_id = ?),
  (select item_name from item_metadata where user_id is null)
  ) item_name;

替换 ?user_id 你要找的。
请看演示。

myss37ts

myss37ts3#

如果您想将此用于一个项目:

select t.*
from t
where item_id = '001'  and
      (user_id = 100 or user_id is null)
order by (user_id is not null)::int desc;

如果您希望所有项目都使用此选项,请使用 distinct on :

select distinct on (item_id) t.*
from t
where user_id = 100 or user_id is null
order by item_id, (user_id is not null)::int desc;

相关问题