mca*_*rox 7 postgresql aggregate full-text-search group-by greatest-n-per-group
我有两张这样的表:
CREATE TABLE cmap5 (
name varchar(2000),
lexemes tsquery
);
Run Code Online (Sandbox Code Playgroud)
和
CREATE TABLE IF NOT EXISTS synonyms_all_gin_tsvcolumn (
cid int NOT NULL, -- REFERENCES pubchem_compounds_index(cid)
name varchar(2000) NOT NULL,
synonym varchar(2000) NOT NULL,
tsv_syns tsvector,
PRIMARY KEY (cid, name, synonym)
);
Run Code Online (Sandbox Code Playgroud)
我目前的查询是:
SELECT s.cid, s.synonym, c.name, ts_rank(s.tsv_syns,c.lexemes,16)
FROM synonyms_all_gin_tsvcolumn s, cmap5 c
WHERE c.lexemes @@ s.tsv_syns
Run Code Online (Sandbox Code Playgroud)
输出是:
cid | synonym | name (query) | rank
5474706 | 10-Methoxyharmalan | 10-methoxyharmalan | 0.0901673
1416 | (+/-)12,13-EODE | 12,13-EODE | 0.211562
5356421 | LEUKOTOXIN B (12,13-EODE) | 12,13-EODE | 0.211562
180933 | 1,4-Chrysenequinone | 1,4-chrysenequinone | 0.211562
5283035 | 15-Deoxy-delta-12,14-prostaglandin J2 | 15-delta prostaglandin J2 | 0.304975
5311211 | 15-deoxy-delta 12 14-prostaglandin J2 | 15-delta prostaglandin J2 | 0.304975
5311211 | 15-deoxy-Delta(12,14)-prostaglandin J2| 15-delta prostaglandin J2 | 0.304975
5311211 | 15-Deoxy-delta-12,14-prostaglandin J2 | 15-delta prostaglandin J2 | 0.304975
5311211 | 15-Deoxy-delta 12, 14-Prostaglandin J2| 15-delta prostaglandin J2 | 0.304975
Run Code Online (Sandbox Code Playgroud)
我想返回cmap5按ts_rank()函数排序的主表中所有行的名称匹配,但对于cmap5我想要的每一行:
cid为每个查询选择最好的 X s ( group by cid)ORDER BY my results as 1+ts_rank/count(cid)为了获得最佳匹配,我尝试添加select distinct on c.name,但是当排名相同时,我希望获得cid更多匹配的查询。我尝试在查询结束时添加一个简单的组,但出现错误,我该怎么做?
添加评论:
一方面,对于那些排名相同的结果,例如。上面5283035和5311211,获得5311211最高结果,因为它的cid点击次数比 多5283035,所以我有点想考虑排名中的点击次数 / cid,例如 final_rank = 1+ts_rank(cid)/no。命中数(cid)。
另一方面,我想获取X每个查询名称的第一个cid。如果我使用LIMIT X它返回X整个查询表的第一个结果,而不是我想要的查询表的X 每个名称(行)的第一个结果。
首先,您PRIMARY KEY跨越两varchar(2000)列似乎非常昂贵。如果您将 PK 用于其他任何用途,我建议使用代理 PK(使用serial列)并添加UNIQUE约束以强制(cid, name, synonym).
如果您的某一varchar列实际使用了最大长度,则您将超过索引条目的最大大小。看:
我想你想要的是这个,因为它是有道理的:
SELECT DISTINCT ON (c.name)
c.name, min(s.synonym) AS min_synonym, s.cid
, ts_rank(s.tsv_syns, c.lexemes, 16) AS rnk
, count(*) AS ct
FROM synonyms_all_gin_tsvcolumn s
JOIN cmap5 c ON c.lexemes @@ s.tsv_syns
GROUP BY c.name, rnk, s.cid
ORDER BY c.name, rnk DESC, ct DESC;
Run Code Online (Sandbox Code Playgroud)
我使用[INNER] JOIN带有附加连接条件的显式替换您的CROSS JOIN加号WHERE子句。它通常被认为是优越的(更容易阅读和调试)。我也使用rnk作为列名来避免基本函数名rank作为标识符。
c.name将具有相同rnk和的结果分组s.cid,采取min(s.synonym)(由于问题中缺乏定义)以及count(*)每组的同级。
减少一排每c.name用DISTINCT ON(SQL标准的Postgres的特定扩展DISTINCT),采取先最高等级和,同一等级内,创同行计数。看:
在一个查询级别中组合GROUP BY和DISTINCT ON这种方式是可能的,因为DISTINCT或DISTINCT ON在之后 应用GROUP BY。
| 归档时间: |
|
| 查看次数: |
44069 次 |
| 最近记录: |