当前位置: 首页 > 知识库问答 >
问题:

使一行中的所有非空值唯一

茹航
2023-03-14

我有一个包含以下列的表:id、col1、col2、col3、col4、col5、col6。

约束表示至少有3列被填充(所以最多3个NULs)。(列不按顺序填充,所以可以有col1、col2、col5被填充,col3、col4、col6是NULs)

如何确保当该列不为NULL时,它在此行的其他列中是唯一的?如何确保非空值的组合在所有行中都是唯一的?

我目前添加了以下约束(以确保至少3个非空):

  ALTER TABLE my_table
    ADD CONSTRAINT my_constraint CHECK (
      (
        (CASE WHEN col1 IS NULL THEN 0 ELSE 1 END) +
        (CASE WHEN col2 IS NULL THEN 0 ELSE 1 END) +
        (CASE WHEN col3 IS NULL THEN 0 ELSE 1 END) +
        (CASE WHEN col4 IS NULL THEN 0 ELSE 1 END) +
        (CASE WHEN col5 IS NULL THEN 0 ELSE 1 END) +
        (CASE WHEN col6 IS NULL THEN 0 ELSE 1 END)
      ) >= 3
    )

共有2个答案

仲承福
2023-03-14

这并不是一个有趣的约束,因为所有的NULL值都是空的,但我认为这确实做到了;

alter table my_table add constraint chk_ugly check
     ( (col1 is null or col1 <> all (array_remove(array[col2, col3, col4, col5, col6], null))) and
       (col2 is null or col2 <> all (array_remove(array[col1, col3, col4, col5, col6], null))) and
       (col3 is null or col3 <> all (array_remove(array[col1, col2, col4, col5, col6], null))) and
       (col4 is null or col4 <> all (array_remove(array[col1, col2, col3, col5, col6], null))) and
       (col5 is null or col5 <> all (array_remove(array[col1, col2, col3, col4, col6], null))) and
       (col6 is null or col6 <> all (array_remove(array[col1, col2, col3, col4, col5], null))) 
     )

我确实认为有一种更好的方法来组织数据,即每个colid一行。那将是一张新桌子。也就是说,很难对强制执行三个价值观加以限制。

注意:您也可以在Postgres中简化现有约束:

ALTER TABLE my_table
    ADD CONSTRAINT my_constraint CHECK (
        cardinality(array_remove(array[col2, col3, col4, col5, col6], null)) >= 3
    )
子车峰
2023-03-14

据我所知,这实际上是三个不同的限制。至少必须存在三个非空值的方法很简单:

ALTER TABLE my_table
   ADD CONSTRAINT my_constraint CHECK ( num_nonnulls(c1, c2, c3, c4, c5, c6) >= 3);

一行的6列中不应存在重复值的要求可以通过创建一个函数来实现:

create or replace function all_unique(p_row my_table)
  returns boolean
as
$$
  select not exists (
    select v
    from (
        values (p_row.c1), (p_row.c2), (p_row.c3), (p_row.c4), (p_row.c5), (p_row.c6)
    ) t(v)
    where v is not null
    group by v
    having count(*) > 1);
$$
language sql
immutable
strict;

如果一行中的所有非空值都是唯一的,则函数返回true。我将其定义为接收完整的行,以便在添加或删除新列时更容易适应。我不确定这是不是最有效或最简单的方法,但我现在想不出其他方法。

这可用于检查约束:

ALTER TABLE my_table
    ADD CONSTRAINT all_unique CHECK ( all_unique(my_table) );

最后一个要求是,跨多行的非空值应该是唯一的,这可以通过一个唯一的索引来实现。但为此,我们需要一个函数,以排序方式创建非空值数组:

create or replace function non_null_values(p_row my_table)
  returns text[]
as
$$
  select array(
    select distinct v
    from (
        values (p_row.c1), (p_row.c2), (p_row.c3), (p_row.c4), (p_row.c5), (p_row.c6)
    ) t(v)
    where v is not null
    order by v);
$$
language sql
immutable
strict;

为什么要分类?因为Postgres认为数组[1,2,3]与数组[3,1,2]不相等(=)。

然后,此函数可用于唯一索引:

create unique index on my_table (non_null_values(my_table));

在线示例

 类似资料:
  • 我有大量数据,需要清理。B列为关键列;如果B列中有空值,则可以删除该行的其余部分。 我在B列上排序,所有的空值都在表的底部。在C-BZ列中有数据,但在B中没有。我想自动识别B中最后一个非空值(假设它是单元格B3841),然后删除工作表底部的3842行。我的数据集每天都在变化。 下面的代码对B列进行排序,然后删除所有完全空的行。我还想删除在B列中为null但在C或D或任何其他行中可能有数据的行。

  • 我有个算法问题。我试图从一个更大的值集合中找到所有唯一的值子集。 例如,假设我有集。我能用什么算法找到3的这些子集? 子集不应重复,且顺序不重要,因此集{1,2,3}与集{3,2,1}相同。鼓励使用Psudocode(或常规类型)。

  • 我有一个使用Spring Data JPA的项目,它使用一个充满地址的表中的数据。这个表格的一列是城市。我想获得表中城市的不同列表,即。 有没有办法使用Spring Data JPA做到这一点?

  • 问题内容: 我需要检查一个JavaScript数组,看看是否有重复的值。最简单的方法是什么?我只需要查找重复的值是什么-我实际上不需要它们的索引或它们被重复多少次。 我知道我可以遍历数组并检查所有其他值是否匹配,但是似乎应该有一种更简单的方法。 问题答案: 您可以对数组进行排序,然后遍历整个数组,然后查看下一个(或上一个)索引是否与当前索引相同。假设您的排序算法很好,则该值应小于O(n 2): 以

  • 问题内容: 我需要在列上计算不同的值,例如: 结果必须是: 3 。我的查询是: 但它返回:2.我还测试了: 但它返回三行: 我怎样才能将空值算作1值,并使用distinct来避免对重复值进行计数? 我正在学习高级SQL,他们希望我对所有解决方案有以下要求: 尝试最小化解决查询所需的子查询数。此外,不允许使用以下构造: 在FROM或SELECT中选择。允许您有子查询(在WHERE或HAVING中进行

  • 问题内容: 有没有一种方法可以通过命令行工具过滤掉文件中的所有唯一行,而无需对行进行排序?我基本上想这样做: 没有排序的性能损失。 问题答案: 删除重复的行: 这是著名的awk单线。关于inet有很多解释。这是一种解释: 这种单线是非常习惯的。它注册在关联数组“ a”中看到的行(数组在Awk中始终是关联的),并同时测试是否看到过该行。如果已经看过前面的行,则a [line]> 0且!a [line