【问题标题】:How to get the matching column name when searching across multiple columns in PostgreSQL?在 PostgreSQL 中搜索多个列时如何获取匹配的列名?
【发布时间】:2021-03-27 20:24:06
【问题描述】:

在 PostgreSQL 中跨多个列进行搜索时,有没有办法获得匹配的列名?

假设我有以下表结构和查询:

CREATE TABLE document (
    id serial PRIMARY KEY,
    document_content VARCHAR
);

CREATE TABLE story (
    id serial PRIMARY KEY,
    headline VARCHAR
);

-----

SELECT
    "document".*,
    story.id,
    story.headline
FROM
    "document"
INNER JOIN story_document AS Documents_join ON "document".id = Documents_join.document_id
INNER JOIN story ON  "story".id = Documents_join.story_id
WHERE to_tsvector(document_content) @@ to_tsquery('foo')
OR to_tsvector(headline) @@ to_tsquery('foo');

我正在考虑连接两列的值,运行全文搜索,然后为两列创建子查询并单独重新运行搜索并将结果记录为参考,但这意味着执行搜索 3 次:

SELECT
    "document".*,
    story.id AS story_id,
    story.headline
    (SELECT "document".id WHERE to_tsvector(document_content) @@ to_tsquery('foo')) AS "matching_document_id",
    (SELECT story_id WHERE to_tsvector(headline) @@ to_tsquery('foo')) AS "matching_story_id"
FROM
    "document"
INNER JOIN story_document AS Documents_join ON "document".id = Documents_join.document_id
RIGHT JOIN story ON "story".id = Documents_join.story_id
WHERE to_tsvector(document_content || ' ' || headline) @@ to_tsquery('foo');

我如何获得对以下列的引用:document_content 或标题,其中关键字“foo”在一个查询中找到?

谢谢!

【问题讨论】:

  • 抱歉,我已经更新了问题。
  • 其实等到两人合体的时候,反正也无所谓了。
  • 这很重要。
  • 你让我很好奇! :D

标签: postgresql subquery full-text-search inner-join


【解决方案1】:

由于列在不同的表中,您可以做的最好的是将OR 转换为UNION

SELECT
    "document".*,
    story.id,
    story.headline
FROM
    "document"
INNER JOIN story_document AS Documents_join ON "document".id = Documents_join.document_id
INNER JOIN story ON  "story".id = Documents_join.story_id
WHERE to_tsvector(document_content) @@ to_tsquery('foo')
UNION
SELECT
    "document".*,
    story.id,
    story.headline
FROM
    "document"
INNER JOIN story_document AS Documents_join ON "document".id = Documents_join.document_id
INNER JOIN story ON  "story".id = Documents_join.story_id
WHERE to_tsvector(headline) @@ to_tsquery('foo');

那么 PostgreSQL 不必为了过滤掉大部分行而构建完整的连接。如果条件是选择性和索引的,并且您在连接条件上也有索引,我的变体将会很快,这样您就可以获得快速的嵌套循环连接。

Here 是关于处理OR 的更多内容。

【讨论】:

  • 谢谢,老实说,我不知道 UNION,会阅读它,但仍然不清楚哪一列是匹配的来源:document_contentheadline。问题是,在客户端,我必须显示对其中一个或另一个的引用。
  • 我用我天真的方法更新了我的问题 - 也许它有助于理解我想要实现的目标,它有效,但它根本不是最佳的。
  • 简单:将两个@@ 表达式添加到结果列表中,然后您将获得两个布尔表达式来告诉您匹配的内容。
  • 感谢您让我看到以上所有内容,非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-12
  • 2020-05-27
  • 1970-01-01
相关资源
最近更新 更多