SQL 查询查找具有最匹配关键字的行

2024-04-16

我真的不擅长 SQL,我想知道我可以运行什么 SQL 来解决下面的问题,我怀疑这是一个 NP 完全问题,但我可以接受查询需要很长时间才能在大型数据集上运行因为这将作为后台任务完成。首选标准 SQL 语句,但如果需要存储过程,那就这样吧。 SQL 需要在 Postgres 9.3 上运行。

问题:给定一组包含一组关键字的文章,找到每篇文章中包含最多匹配关键字的前 n 篇文章。

文章表的精简版本如下所示:

CREATE TABLE article (
  id character varying(36) NOT NULL,  -- primary key of article
  keywords character varying,         -- comma separated set of keywords

  CONSTRAINT pk_article PRIMARY KEY (id)
);

-- Test Data
INSERT INTO article(id, keywords) VALUES(0, 'red,green,blue');
INSERT INTO article(id, keywords) VALUES(1, 'red,green,yellow');
INSERT INTO article(id, keywords) VALUES(2, 'purple,orange,blue');
INSERT INTO article(id, keywords) VALUES(3, 'lime,violet,ruby,teal');
INSERT INTO article(id, keywords) VALUES(4, 'red,green,blue,yellow');
INSERT INTO article(id, keywords) VALUES(5, 'yellow,brown,black');
INSERT INTO article(id, keywords) VALUES(6, 'black,white,blue');

这会导致SELECT * FROM article; query:

Table: article
------------------------
id  keywords            
------------------------
0   red,green,blue      
1   red,green,yellow    
2   purple,orange,blue  
3   lime,violet,ruby,teal
4   red,green,blue,yellow
5   yellow,brown,black
6   black,white,blue

假设我想找到每篇文章中包含最多匹配关键字的前 3 篇文章,那么输出应该是这样的:

------------------------
id  related
------------------------
0   4,1,6
1   4,0,5
2   0,4,6
3   null
4   0,1,6
5   1,6
6   5,0,4

Like @a_horse 评论了 https://stackoverflow.com/questions/31512506/sql-query-for-finding-maximum-matching-keywords-in-articles/31513001#comment50986752_31512506:使用标准化设计会更简单(除了使其他任务更简单/更清晰),但是仍然不是微不足道的.

另外,数据类型的 PK 列character varying(36)高度可疑(且效率低下),很可能应该是integer type https://www.postgresql.org/docs/current/datatype-numeric.html#DATATYPE-INT或至少一个uuid https://www.postgresql.org/docs/current/datatype-uuid.html反而。

根据您的情况,这是一种可能的解决方案按原样设计:

WITH cte AS (
   SELECT id, string_to_array(a.keywords, ',') AS keys
   FROM   article a
   )
SELECT id, string_agg(b_id, ',') AS best_matches
FROM  (
   SELECT a.id, b.id AS b_id
        , row_number() OVER (PARTITION BY a.id ORDER BY ct.ct DESC, b.id) AS rn
   FROM   cte a
   LEFT   JOIN cte b ON a.id <> b.id AND a.keys && b.keys
   LEFT   JOIN LATERAL (
      SELECT count(*) AS ct
      FROM  (
         SELECT * FROM unnest(a.keys)
         INTERSECT ALL
         SELECT * FROM unnest(b.keys)
         ) i
      ) ct ON TRUE
   ORDER  BY a.id, ct.ct DESC, b.id  -- b.id as tiebreaker
   ) sub
WHERE  rn < 4
GROUP  BY 1;

sqlfiddle http://sqlfiddle.com/#!15/a7de8/4(使用整数id反而)。

The CTE cte将字符串转换为数组。你甚至可以有一个像这样的功能性 GIN 索引......

如果前 3 个选择有多个行,您需要定义一个决胜局。在我的示例中,具有较小的行id先来吧。

详细解释在最近的相关答案中:

  • 按 JSON 数组中的匹配数进行查询和排序 https://stackoverflow.com/questions/30557511/query-and-order-by-number-of-matches-in-json-array/31467595#31467595

比较是在 JSON 数组和 SQL 数组之间进行的,但基本上是相同的问题,归结为相同的解决方案。还比较了几个类似的替代方案。

为了加快速度,您至少应该在数组列上有一个 GIN 索引(而不是逗号分隔的字符串),并且查询不需要 CTE 步骤。完全规范化的设计还有其他优点,但不一定比具有 GIN 索引的数组更快。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SQL 查询查找具有最匹配关键字的行 的相关文章

  • 将 SQL Server 2008 DB 迁移到 Postgres [重复]

    这个问题在这里已经有答案了 我想将 SQL Server 2008 数据库迁移到 Postgres 有没有一种无痛的方法来做到这一点 是否有任何工具可以扫描架构和存储过程以标记兼容性问题 无痛http dbconvert com conve
  • MySQL NOT IN 来自同一个表中的另一列

    我想运行 mysql 查询来选择表中的所有行films其中的值title该列不存在于另一列的所有值中的任何位置 collection 这是我的表格的简化版本 其中包含内容 mysql gt select from films id titl
  • JPA 支持查询 Postgres JSON 字段

    JPA 是否已经支持处理 JSON 字段的查询 如下所示 select from person where info gt gt age numeric 40 select from person where info gt gt firs
  • MYSQL:如何在同一查询中联接两个表,两次引用同一个表

    我有两张桌子 我正在尝试将下面的示例两个表与表 1 引用表 2 两次结合起来 例如 如果我查看表 1 组 2 和成员 7 它应该查找表 2 中的 ID 并给出输出 Group Members Name Name 2 7 Blue Dog T
  • 如何在 SQL Server 2012 中选择除一列之外的所有列? [复制]

    这个问题在这里已经有答案了 有没有一种方法可以选择所有列 但只选择我不想选择的特定列 我的意思是有时我会遇到这样的问题 表有数百个字段 而我只需要删除一个字段 我需要重写所有列吗 有什么窍门吗 喜欢select
  • 基本的多对多sql选择查询

    我认为这应该很容易 但它却在逃避我 我的帐户和帐户组之间存在多对多关系 一个帐户可以位于零个或多个组中 因此我使用标准连接表 Accounts ID BankName AcctNumber Balance AccountGroups ID
  • 使用函数的 SQL 查询 - 如何获取列表的最大计数

    如何查询 MAXIMUM COUNT 交易次数 我的代码如下 SELECT customer id COUNT customer id FROM rental GROUP BY customer id HAVING MAX COUNT cu
  • mysql GROUP_CONCAT 重复项

    我从 farmTOanimal 表中进行连接 如下所示 有一个类似的farmTotool表 id FarmID animal 1 1 cat 2 1 dog 当我在视图中加入表时 我得到的结果如下所示 FarmID animal tool
  • SQL Server - 选择满足条件的第一行

    我有 2 个包含 ID 的表 其中一个表中会有重复的 ID 我只想为表 B 中的每个匹配 ID 返回一行 例如 Table A objectIdA objectIdB 1 A 1 B 1 D 5 F Table B objectIdA 1
  • 仅选择 Varchar 列中的数字[重复]

    这个问题在这里已经有答案了 在 SQL Server 2008 R2 中 我在 varchar 12 列中有一些数据 它看起来像这样 Data 1234 1765 34566 123 SDRMH HJG434 我想从所有包含 的行中删除 并
  • Rails 中 WHERE 子句中的 ALL 运算符

    关联关系如下图所示 InstructorStudent has many fees Fee belongs to instructor student 我想要获得在所有给定数组中具有每月详细信息的指导学生 如果其中任何一个中不存在每月详细信
  • 如何修复“缺少表的 FROM 子句条目”错误

    我正在尝试根据游戏 ID 获取平台名称 我有如下三个表 我正在尝试加入它们以获得所需的结果 Games Id 1 2 3 4 Game Platforms Id game id platform id 1 1 1 2 1 2 3 3 3
  • mysql 详细查询字符串,如通配符

    不知道如何标题我的问题 哈哈 下面是我需要的 我的数据库中的值如下所示 test example 1 test example 2 test example TD 1 这些值的长度可以不同 test example 只是一个示例 某些值将具
  • SQL中如何识别字符串的第一个字符是数字还是字符

    我需要将数据中的第一个字符识别为 SQL Server 中的数字或字符 我对此比较陌生 我不知道从哪里开始 但这是我到目前为止所做的事情 我的数据看起来像这样 TypeDep Transfer From 4Z2 Transfer From
  • postgresql中的按日期聚合函数分组

    我在运行此查询时遇到错误 SELECT date updated at count updated at as total count FROM persons WHERE persons updated at BETWEEN 2012 1
  • 查询嵌套查询结果中两列的位置

    我正在编写这样的查询 select from myTable where X in select X from Y and XX in select X from Y X 列和 XX 列的值必须位于同一查询的结果中 select X fro
  • 如何避免连接两个表时重复

    Student Table SID Name 1 A 2 B 3 C Marks Table id mark subject 1 50 physics 2 40 biology 1 50 chemistry 3 30 mathematics
  • 访问数据库 LIMIT 关键字

    我试图让我的页面列表功能在 ASP 中与 Access 数据库一起工作 但我不知道 Microsoft SQL 中 LIMIT 的替代方案 我已经尝试过 TOP 但这似乎不起作用 这是 MySQL 中使用的语句 SELECT FROM cu
  • 使用所有连接的 Flask unittest 和 sqlalchemy

    在进行了大约 100 个单元测试后 我刚刚在 Flask 应用程序上运行单元测试时遇到了问题 所有单元测试都会通过 但是当一次全部运行时 它们将失败并出现以下错误 OperationalError OperationalError FATA
  • SQL Server 2008 R2 内连接无法匹配 varchar 字段,因为它包含特殊字符

    我们正在将 Microsoft SQL Server 2008 R2 用于我们的经典 ASP 应用程序之一 我们有两张表 TableA TableB TableA有以下列 InstName varchar 1024 TableB有这些列 I

随机推荐

  • 如何使用 Homebrew cask 安装 Sublime Text 3

    如何使用 Homebrew cask 安装 Sublime Text 3 当使用 Homebrew 的搜索时 我只看到 Sublime Text 2 我什至尝试点击自制软件 版本 https github com Homebrew home
  • 最容易实现的 Voronoi 图算法? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 实现 Voronoi 图的简单算法有哪些 我找不到任何专门以伪形式出现的算法 请分享一些 Vorono
  • 新值 EditText 未显示,没有任何错误

    编辑 顺便说一句 如果我在范围内硬编码 edt4 setText any text 它会显示该值 编辑2 尝试重建 清理项目 这可能是 settext 方法中的错误 看起来我做得对 当我用 settext 查看其他代码时 编辑3 start
  • 编译为 WebAssembly 时无法使 image::load_from_memory() 工作

    我正在尝试使用 Rust 将图像从 JavaScript 加载到 WebAssembly图像箱 https crates io crates image 我有以下 Rust 代码 extern crate image extern crat
  • 如何解决 Eclipse 中未解决的包含:

    我在 eclipse 中构建了一个简单的程序 include
  • SimpleDateFormat 在模拟器上工作正常,但在设备上错误

    我使用 SimpleDateFormat 从日期中提取相关信息 它在模拟器中运行得很好 但是在设备上测试时它无法正确格式化 Logcat 在模拟器中正确显示 但在手机上再次显示错误 private String getSectionHead
  • 在生产中使用 Postgres 配置 Rails

    我一直在谷歌上搜索有关如何将 Ruby on Rails 与 PostgreSQL 结合使用的教程 那里有一些非常好的信息 但几乎每个指南都集中在如何配置 Rails 以在开发和测试环境中使用 Postgres 他们会警告您不要将这些配置用
  • 当项目中有多个文件时,如何使用 Grunt 配置 LESS 的 sourceMap?

    我有多个 less 文件 我希望将它们处理为匹配的 css 每个文件的 sourceMaps 都与源位于同一文件夹中 这有多难 我用 less 直接执行此操作没有问题 但无法弄清楚如何在 grunt contrib less 中执行此操作
  • RESTful 设计:分页集合

    我正在设计一个 REST api 需要从服务器端强制执行分页 每个 x 翻阅任何资源集合的正确方法是什么 选项1 GET resource page
  • Swift @escaping 和完成处理程序

    我试图更准确地理解 Swift 的 闭包 But escaping and Completion Handler太难理解了 我查了很多Swift的帖子和官方文档 但感觉还是不够 这是官方文档的代码示例 var completionHandl
  • 如何向 Google 地图上的信息窗口添加组合框和按钮?

    目前 我正在开发一个应用程序 其中我必须在地图本身的单击事件上显示一个信息窗口 我的问题是我想在此信息窗口上显示一个按钮和一个组合框 我怎样才能做到这一点 您需要添加自定义UIView给你的MK地图视图并抑制默认值MK注释标注视图 您的定制
  • 在 Chrome 中无需右键单击即可检查元素

    When I inspect html css on a website I usually open the chrome developers panel ctrl shift I right click context menu in
  • 如何通过着色器管道传递顶点颜色?

    我试图通过顶点 几何和片段着色器传递顶点颜色 glBegin GL POINTS glVertex3f 2 0f 0 0f 0 0 glColor3f 0 0 1 0 0 0 glVertex3f 2 0f 0 0f 0 0 glColor
  • jQuery while 循环不等待动画

    我有一个 jQuery 函数可以执行以下操作 clone 在一个物体上 然后 insertAfter and a slideDown 在克隆的对象上 整个函数被包装在一个while环形 我将尽可能简短并展示一个通用示例 while stat
  • 将函数应用于不包括按值嵌套的数据表子集

    我有一个与此相关的问题 我之前曾问过 从 foreach 循环赋值 https stackoverflow com questions 18767016 assignment of a value from a foreach loop 1
  • Laravel 5 调整图像大小

    我使用 Laravel 5 并有一个上传图像的表单 保存文件时 我在控制器方法中获取图像并将其放入目录中 if request gt hasFile picture destinationPath uploads filename imag
  • jQuery-tokeninput 失败:“term”未定义?

    在我的 Rails 应用程序中 我尝试使用 jquery tokeninput 我一切正常 json 响应和所有 但当在标记化字段中输入任何内容时 脚本会出错 并抱怨 TypeError term is undefined gt retur
  • 如何阻止 Maven 覆盖资源文件

    我有默认的 Maven 结构 main java resources webapp 我看到每个mvn compile复制资源 即使它们没有改变 我应该怎么做才能仅复制更改的文件
  • 无法以管理员身份运行

    我必须执行ewfmgr exe仅当以管理员身份打开命令窗口时才能执行 如果我去Start gt type cmd exe gt Right click gt Run as Administrator然后出现以下命令提示符窗口 在这个窗口中
  • SQL 查询查找具有最匹配关键字的行

    我真的不擅长 SQL 我想知道我可以运行什么 SQL 来解决下面的问题 我怀疑这是一个 NP 完全问题 但我可以接受查询需要很长时间才能在大型数据集上运行因为这将作为后台任务完成 首选标准 SQL 语句 但如果需要存储过程 那就这样吧 SQ