【问题标题】:SQL index based search基于 SQL 索引的搜索
【发布时间】:2016-11-20 10:09:02
【问题描述】:

我有一个名为Index 的表,其中包含idvalue 列,其中id 是一个自动递增的bigint,value 是一个带有英文单词的varchar。

我有一个名为Search 的表,它与表Index 有关系。对于每个搜索,您可以定义它应该在名为 Article 的表中搜索哪些索引。

Article也与表Index有关系。

定义关系的表是:

Searches_Indexes 与列 id_searchid_index

Articles_Indexes 与列 id_articleid_index

我想查找所有包含相同搜索索引的文章。

例如:我有一个Search,索引为laptopdell,我想检索所有包含两个索引的Articles,而不仅仅是一个。

到目前为止,我有这个:

SELECT ai.id_article 
FROM articles_indexes AS ai 

INNER JOIN searches_indexes AS si 
ON si.id_index = ai.id_index 

WHERE si.id_search = 1

如何让我的 SQL 只返回 Articles 以及 Search 的所有 Indexes?

编辑:

样本数据:

文章:

id | name          | description           | ...
1  | 'Dell Laptop' | 'New Dell Laptop...'  | ...
2  | 'HP Laptop'   | 'Unused HP Laptop...' | ...
...

搜索:

id | name                 | id_user | ...
1  | 'Dell Laptop Search' | 5       | ...

索引:

id | value
1  | 'dell'
2  | 'laptop'
3  | 'hp'
4  | 'new'
5  | 'unused'
...

Articles_Indexes:

Articleid 1(戴尔笔记本电脑)具有 Indexes 'dell'、'laptop'、'new'。

Articleid 2(hp 笔记本电脑)具有 Indexes 'laptop'、'hp'、'unused'。

id_article | id_index
1          | 1
1          | 2
1          | 4
...
2          | 2
2          | 3
2          | 5
...

Searches_Indexes:

Searchid 1 仅包含 2 个 Indexes、“戴尔”和“笔记本电脑”:

id_search | id_index
1         | 1
1         | 2

所需输出:

id_article
1

【问题讨论】:

  • 表称为搜索和索引...您还有哪些其他表 - 列、位置、选择和值?
  • 已更新以使其更加清晰。我有两个关系表Searches_IndexesArticles_Indexes,它们基本上定义了哪些搜索有哪些索引,哪些文章有哪些索引。
  • edit 您的问题并添加一些示例数据和基于该数据的预期输出。 Formatted 文本no screen shots
  • @a_horse_with_no_name 我已经用示例数据更新了我的问题。
  • 顺便说一句Full Text Search

标签: sql postgresql search indexing


【解决方案1】:

如果我理解正确,您需要聚合和 HAVING 子句。假设索引表中没有重复条目:

SELECT ai.id_article 
FROM articles_indexes ai INNER JOIN
     searches_indexes si 
     ON si.id_index = ai.id_index 
WHERE si.id_search = 1
GROUP BY ai.id_article
HAVING COUNT(*) = (SELECT COUNT(*) FROM searches_indexes si2 WHERE si2.id_search = 1);

这会计算匹配的数量并确保它与您要查找的数字匹配。

我应该添加这个。如果您想同时查找所有搜索,我倾向于将其写为:

SELECT si.id_search, ai.id_article 
FROM articles_indexes ai INNER JOIN
     (SELECT si.*, COUNT(*) OVER (PARTITION BY si.id_index) as cnt
      FROM searches_indexes si 
     ) si
     ON si.id_index = ai.id_index 
GROUP BY si.id_search, ai.id_article, si.cnt
HAVING COUNT(*) = si.cnt;

【讨论】:

    【解决方案2】:

    您可以比较数组。举个例子:

    create table article_index(id_article int, id_index int);
    create table search_index(id_search int, id_index int);
    
    insert into article_index
    select generate_series(1,2), generate_series(1,10);
    insert into search_index
    select generate_series(1,2), generate_series(1,4);
    
    select 
        id_article
    from article_index
    group by id_article
    having array_agg(id_index) @> (select array_agg(id_index) from search_index where id_search = 2);
    

    Learn more 关于 postgres 中的数组。

    【讨论】:

      猜你喜欢
      • 2014-11-12
      • 2011-02-21
      • 1970-01-01
      • 2010-10-31
      • 2017-03-20
      • 2013-12-20
      • 1970-01-01
      • 2015-06-21
      相关资源
      最近更新 更多