Postgres查询返回基于模糊匹配的记录与集合中的值

时间:2016-12-17 20:17:59

标签: sql postgresql

如下所示,我有两个表,一个包含有关人的信息,另一个包含有关体育的信息。

我想在人员表上进行查询,只返回描述中包含费用表中列出的运动的记录。如果描述仅包含运动,而没有其他文本,我可以轻松地将此作为内部联接,将所有内容切换为小写。但是,我正在考虑因为描述中的其他信息,我可能需要对子查询和/或正则表达式执行某些操作。

 name  | age |               description                
-------+-----+------------------------------------------
 bill  |  15 | I like to play soccer
 bob   |  20 | In my free time, I like to play BASEBALL
 jim   |  25 | I play video games everyday!!
 tony  |  30 | Im a really big fan of Hockey!!
 sandy |  35 | I could play soccer and hockey everyday


  sport   | cost 
----------+------
 soccer   |  100
 baseball |  150
 hockey   |  200

最终,此查询将返回下表,其中不包含jim,因为他的描述中的所有单词都不在成本表的运动列中。有时候运动可能是一个单词,有时可能是多个单词。如果体育运动包含多个单词,我希望所有这些单词一起出现在说明中以便返回。

 name  | age |               description                
-------+-----+------------------------------------------
 bill  |  15 | I like to play soccer
 bob   |  20 | In my free time, I like to play BASEBALL
 tony  |  30 | Im a really big fan of Hockey!!
 sandy |  35 | I could play soccer and hockey everyday

我知道我可以为每项运动单独做这件事,但我希望有更好的方法来做到这一点。

SELECT *
FROM person
WHERE lower(description) LIKE '%hockey%';

 name  | age |               description               
-------+-----+-----------------------------------------
 tony  |  30 | Im a really big fan of Hockey!!
 sandy |  35 | I could play soccer and hockey everyday

创建下面的表格的代码

CREATE TABLE person (name VARCHAR(10), age INT, description VARCHAR(100));
INSERT INTO person (name, age, description) VALUES ("bill", 15, "I like to play soccer")
INSERT INTO person (name, age, description) VALUES ("bob", 20, "In my free time, I like to play BASEBALL")
INSERT INTO person (name, age, description) VALUES ("jim", 25, "I play video games everyday!!")
INSERT INTO person (name, age, description) VALUES ("tony", 30, "Im a really big fan of Hockey!!")
INSERT INTO person (name, age, description) VALUES ("sandy", 35, "I could play soccer and hockey everyday")

CREATE TABLE cost (sport VARCHAR(10), cost INT);
INSERT INTO cost (sport, cost) VALUES ('soccer', 100);
INSERT INTO cost (sport, cost) VALUES ('baseball', 150);
INSERT INTO cost (sport, cost) VALUES ('hockey', 200);

1 个答案:

答案 0 :(得分:1)

您可以使用联接:

SELECT DISTINCT p.name,p.age,p.description
FROM person p
  JOIN cost c ON p.description LIKE '%'||c.sport||'%'

DISTINCT是必要的,以避免为Sandy获取两行。

或者,您可以使用EXISTS和子查询:

SELECT p.name,p.age,p.description
FROM person p
WHERE EXISTS (
  SELECT 1
  FROM cost c
  WHERE p.description LIKE '%'||c.sport||'%')

EXISTS检查子查询是否至少返回一行,因此它与子查询中的选择无关。那为什么不1?