sql - 组之间的 SQL (PostgreSQL) 唯一值
问题描述
我有一个包含 val_A、val_B 列的表。要求我只能插入(没有更新/删除,我想避免触发器和存储过程)。
我如何实现这样的要求,即列 val_A 的值必须是唯一的,但不是整个表,而是基于 val_B 的组。换句话说,对于 val_B = 1,我可以有许多 val_A = 1 的条目,但在这种情况下,我不能让 val_A = 1 和 val_B != 1;
例如:
+-------+-------+---------------------+
| val_A | val_B | Comment |
+-------+-------+---------------------+
| 1 | 1 | |
| 2 | 1 | |
| 1 | 1 | This is Allowed |
| 1 | 2 | This is not allowed |
+-------+-------+---------------------+
编辑#1 我正在寻找的解决方案应该适用于当前的插入。我正在尝试类似于Davide Anghileri响应的东西,但在并发插入场景中失败了。
解决方案
NULL
这很棘手,但您可以在表达式上创建唯一索引 - 并使用 Postgres 允许值在唯一索引中重复的事实。
所以:
create unique index unq_t_val_a_val_b on
(case when val_a <> val_b then least(val_a, val_b) end,
case when val_a <> val_b then greatest(val_a, val_b) end
);
当值不least()
同时,然后greatest()
创建一个索引,其中包含两个键,值按顺序排列。当值相同时,键是这样的,NULL
因此它们实际上并不是唯一索引的一部分。
你也可以通过过滤来做到这一点:
create unique index unq_t_val_a_val_b on
(least(val_a, val_b), greatest(val_a, val_b))
where val_a <> val_b;
推荐阅读
- javascript - Yammer JS SDK:使用 Yammer 登录按钮会打开弹出窗口,但从不关闭它。Yammer JS 开发工具包
- mac-address - getMac npm 角度 cli
- rx-java - RxJava:如何取消订阅 observable 的主题
- javascript - 我们为什么要使用 Redux?它对我们有什么帮助?
- react-native - metro 显示当前FocusedField 已弃用,将来将被删除
- git - 我们可以在分支上创建一个空提交而不切换到它吗
- java - 从 spring-boot 中的 application.yml 文件中获取 cron
- android - 如何从主应用程序(Android Studio)中的导入模块开始活动?
- sql - 当一列有不同的数据时如何返回 1 行而不是 3 行
- javascript - 选择组件渲染