有没有办法像自定义分隔符一样选择

时间:2016-04-17 11:56:32

标签: sql postgresql sql-like

我有postgresql表,如下所示:

+----+---------------------+
| id |        names        |
+----+---------------------+
|  1 | foo|bar and biz|pop |
+----+---------------------+

我想选择包含给定名称的行。像

这样的东西
SELECT "id" FROM "table" WHERE "names" LIKE '%foo%';
 id
-----
1
(1 row)

如果我要求bar and biz,我希望查询返回此行,但如果我从bar询问,则不返回任何内容。

现在我将管道符号添加到行的开头和结尾,并询问LIKE '%|bar and biz|%'。无论如何,我想知道是否有办法找到没有额外管道的行。

有没有办法在postgresql中进行这样的查询?

UPD:好像我解释我的问题不好。好吧,我想要关注:

SELECT "id" FROM "table" WHERE "names" LIKE '%bar and biz%';
 id
-----
1
(1 row)

SELECT "id" FROM "table" WHERE "names" LIKE '%bar%';
 id
-----
(0 rows)

5 个答案:

答案 0 :(得分:2)

首先,将多个值存储在一列中是一个坏主意:

  • SQL不太擅长字符串操作。
  • 此类操作无法使用索引。
  • 您不能使用外键关系来验证值。

相反,您应该使用联结表。 Postgres还有其他存储列表的解决方案,例如数组和JSON。

有时,我们会遇到其他人糟糕的设计决策。使用like的一种方法是:

SELECT "id"
FROM "table"
WHERE '|' || "names" || '|' LIKE '%|bar|%';

答案 1 :(得分:2)

虽然您遇到了不幸的设计,但转换为数组并使用ANY构造:

SELECT id
FROM   table
WHERE  'bar' = ANY (string_to_array(names, '|'));

关于ANY@>,数组和索引:

答案 2 :(得分:1)

您是否尝试过以下操作?

where "names" = 'foo' or
      "names" LIKE 'foo|%' or 
      "names" LIKE '%|foo' or
      "names" LIKE '%|foo|%'

答案 3 :(得分:1)

由于您的专栏已经与' |'分开了您可以将其强制转换为数组,并使用contains来获得所需的结果

SELECT "id"
FROM "table"
WHERE string_to_array(names, '|')::varchar[] @> '{bar}'::varchar[];

答案 4 :(得分:0)

我刚刚检查了我的系统,它对我来说很好。首先,我不明白你为什么在列名中有双引号。不建议这样做。

我的表架构

CREATE TABLE table (
  id int(11) unsigned NOT NULL AUTO_INCREMENT,
  names varchar(255) DEFAULT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

为了获取数据,我使用了这个

SELECT id FROM table WHERE names LIKE '%foo%' or names LIKE '%bar and biz%';

更新: -

SELECT * FROM A WHERE names LIKE '%bar%';

enter image description here

从coulmn名称和表名中删除双引号。