【问题标题】:Compare two PostgreSQL columns with strings separated by slash "/" or parentheses "( )"比较两个 PostgreSQL 列,字符串由斜杠“/”或括号“()”分隔
【发布时间】:2015-11-24 12:22:05
【问题描述】:

我对 Rails/PostgreSQL 还很陌生,只是陷入了这个看似简单的问题。

当一列包含不同语言的同一事物的多个字符串值时,如何比较两列的字符串值,用斜杠“/”或括号“( )”分隔?

ID |    Drink #1   |     Drink #2
 1 |      Water    |   Agua/Water/Eau
 2 |    Magnesium  | Magnesio (Magnesium)

我主要是在寻找 PostgreSQL 查询以显示在“饮料 #1 和饮料 #2 都包含水和镁”视图中,但我也想知道是否有其他方法可以使用控制器(MVC 的 C) .我搜索了相关的 Rails Gems,但几个小时后没有成功。

谢谢大家!

【问题讨论】:

  • 不就是搜索子串吗?搜索饮料 #2 中是否存在饮料 #1?
  • 你的预期输出是什么。

标签: sql ruby-on-rails postgresql string-comparison


【解决方案1】:

只需检查drink1是否是drink2的子串:

select *
from drinks
where drink2 like format('%%%s%%', drink1);

 id |  drink1   |        drink2
----+-----------+----------------------
  1 | Water     | Agua/Water/Eau
  2 | Magnesium | Magnesio (Magnesium)
(2 rows)

检查drink1 是否严格属于drink2 除以/

select *
from drinks
where drink1 = any(string_to_array(drink2, '/'));

 id | drink1 |     drink2
----+--------+----------------
  1 | Water  | Agua/Water/Eau
(1 row)

检查drink2是否在括号中包含drink1

select *
from drinks
where drink2 like format('%%(%s)%%', drink1);

 id |  drink1   |        drink2
----+-----------+----------------------
  2 | Magnesium | Magnesio (Magnesium)
(1 row)

查询 #2 和 #3 合二为一:

select *
from drinks
where drink1 = any(string_to_array(drink2, '/'))
or drink2 like format('%%(%s)%%', drink1);

 id |  drink1   |        drink2
----+-----------+----------------------
  1 | Water     | Agua/Water/Eau
  2 | Magnesium | Magnesio (Magnesium)
(2 rows)

2015 年 9 月 2 日更新

drink2 列中有两种语法形式。 形式可以被认为是对称(带斜线)和不对称(带括号)。 您应该将 asymmetric 项转换为 symmetric 项。 可以使用函数replace() and translate():

select *, replace(translate(drink2, '()', '/'), ' /', '/')
from drinks

 id |  drink1   |        drink2        |      replace
----+-----------+----------------------+--------------------
  1 | Water     | Agua/Water/Eau       | Agua/Water/Eau
  2 | Magnesium | Magnesio (Magnesium) | Magnesio/Magnesium
(2 rows)    

您的查询可能如下所示:

select *
from drinks
where drink1 = any(string_to_array(replace(translate(drink2, '()', '/'), ' /', '/'), '/'));

【讨论】:

  • 实际上,还有一个关于括号的问题:如果 Drink 2(第二列)包含 'Magnesium (Magnesio)' - 即要比较的字符串值不在括号内怎么办?我不确定是否可以使用子字符串查询,因为这样的查询会在“硫酸镁”之类的情况下导致误报,这与“镁”不同。
猜你喜欢
  • 1970-01-01
  • 2019-05-08
  • 1970-01-01
  • 2021-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-23
相关资源
最近更新 更多