SQL'ab,cd'与'cd,ab'相比是正确的

时间:2014-05-28 07:35:54

标签: sql postgresql preg-match

我在postgresql中有一点情况

我有两个表t1和t2,两个表都有一个具有相同类型数据'col_data'的列, col_data可能只有以下数据('ab','cd','ab,cd','cd,ab')

我想在t1.col_data ='ab,cd'和t2.col_data ='cd,ab'

时比较t1.col_data和t2.col_data时返回TRUE

1 个答案:

答案 0 :(得分:5)

正确的解决方案是修复您的数据模型,这样您就不会在文本字段中将复合数据存储为逗号分隔值;见this post

短期解决方法可能是定义“commasep_to_sorted_array”函数,例如:

CREATE OR REPLACE FUNCTION commasep_to_sorted_array(text) RETURNS text[] AS $$
SELECT array_agg(t ORDER BY t) FROM regexp_split_to_table($1,',') t;
$$ LANGUAGE sql IMMUTABLE;

然后在你的比较中使用它:

commasep_to_sorted_array(t1.col_data) = commasep_to_sorted_array(t2.col_data)

毋庸置疑,这是无法索引的。虽然你可以创建一个在某些情况下有用的表达式索引。

如果您的案例非常简单,只有四个可能的值,您可以将列转换为枚举:

CREATE TYPE abcd AS ENUM (
   'ab', 'cd', 'ab,cd', 'cd,ab'
);

ALTER TABLE mytable ALTER COLUMN col_data TYPE abcd USING (col_data::abcd);

(虽然我真的希望真实姓名比这更有用!)

如果你真的将它们视为两个独立的标志,那么值可以是“既不是ab也不是cd”,“只是ab”,“只是cd”,或“ab和cd”,那么你应该这样建模相反 - 你手动测试位的两个布尔字段,一个位域或一个int字段。我更喜欢两个布尔字段,没有充分的理由不这样做。