从正则表达式中获取子字符串 - 一切都是字符

时间:2016-06-30 19:37:22

标签: regex postgresql database-design pattern-matching

有一个问题表,其中包含一个名为options的列,其中包含

'r>>>>>5####answer1|4####answer2|3####answer3|2####answer4|1####answer5'

哪一对可能的答案

  • 5 = answer1
  • 4 = answer2

问题由用户设置,但模式相同。

另一个表的用户答案是选中的选项。我正在尝试编写SQL来提取答案文本。

例如4应显示answer2

我试过了:

SELECT substring(question.options from '%4####@"%@"[\|]%' for '@') AS answertext
FROM ...

但它会显示answer2|3####answer3|2####answer4

如何获取第一个|的所有内容?

1 个答案:

答案 0 :(得分:1)

正则表达式supplied by @Abelisto in a comment效果很好。您不需要在字符类中转义|,因此它可以是:

SELECT substring(options, '4#+([^|]+)' ...

假设答案的数量仅限于单个数字,那么也有一个没有正则表达式的简单解决方案:

SELECT right(x, -5) AS answer
FROM   unnest( string_to_array(right(
         'r>>>>>5####answer1|4####answer2|3####answer3|2####answer4|1####answer5'
       , -6), '|')) x
WHERE  x LIKE '4%';  -- pick number

适用于您的桌子:

SELECT right(x, -5) AS answer
FROM   question q, unnest( string_to_array(right(q.options, -6), '|')) x
WHERE  q.question_id = 1
AND    x LIKE '4%';

但实际上,你应该normalize你不幸的设计。这是问答之间的1:n设计。假设PK question.question_id你可以像这样快速修复它:

CREATE TABLE answer AS
SELECT q.question_id, left(x,1)::int AS answer_id, right(x, -5) AS answer
FROM   question q, unnest(string_to_array(right(q.options, -6), '|')) x;

ALTER TABLE answer
   ADD PRIMARY KEY (question_id, answer_id)
 , ADD CONSTRAINT q_fk FOREIGN KEY (question_id) REFERENCES question(question_id)
       ON UPDATE CASCADE ON DELETE CASCADE;

ALTER TABLE question DROP column options;

然后你的查询就是:

SELECT answer
FROM   answer
WHERE  question_id = 1
AND    answer_id = 4;

相关: