次のような2つのテーブルがあります。
_CREATE TABLE cmap5 (
name varchar(2000),
lexemes tsquery
);
_
そして
_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)
);
_
私の現在のクエリは:
_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
_
そして出力は:
_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
_
ts_rank()
関数によってランク付けされたメインテーブルの_cmap5
_のすべての行の名前の一致を返したいのですが、_cmap5
_の各行について、次のことを実行します。
cid
sのみを選択(_group by cid
_)ORDER BY my results as 1+ts_rank/count(cid)
最適な一致を得るために_select distinct on c.name
_を追加しようとしましたが、ランクが同じである場合は、クエリにさらに一致するcid
を取得します。クエリの最後に簡単なグループを追加しようとしましたが、エラーが発生しました。どうすればよいですか?
追加されたコメント:
一方では、ランクが同じである結果、たとえば上記の_5283035
_および_5311211
_の場合、cid
は_5311211
_よりもヒット数が多いため、上位の結果として_5283035
_を取得します。ヒット数/ランク内のcid
、final_rank = 1 + ts_rank(cid)/ noなど。ヒット数(cid)。
一方、クエリ名ごとに最初のX
cidsを取得したいと思います。 _LIMIT X
_を使用すると、クエリテーブルの最初のX
ではなく最初のX
結果が返されます名前ごと(行)私が望むように。
まず、2つのvarchar(2000)
列にまたがる_PRIMARY KEY
_は非常に高価に見えます。他の目的でPKを使用する場合は、代理PK( serial
column を使用)を提案し、UNIQUE
制約を追加して_(cid, name, synonym)
_に一意性を適用します。
varchar
列の1つが実際に最大長を使用する場合、インデックスエントリの最大サイズを超えます。見る:
私は推測あなたが望むのはこれです、それは理にかなっているので:
_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;
_
明示的な_[INNER] JOIN
_を使用し、_CROSS JOIN
_プラスWHERE
句の代わりに、結合条件を付加します。これは一般的に優れている(読み取りとデバッグが容易)と考えられています。また、列名としてrnk
を使用して、基本的な関数名rank
を識別子として回避しています。
rnk
と_c.name
_が同じ_s.cid
_ごとに結果をグループ化し、min(s.synonym)
(質問の定義がない場合)、およびcount(*)
グループごとのピア。
_c.name
_(SQL標準DISTINCT
のPostgres固有の拡張)を使用して_DISTINCT ON
_ごとに1行に減らし、最も高いランクを最初に、同じランク内で最も高いピアカウントを取得します。見る:
_GROUP BY
_と_DISTINCT ON
_をこのように1つのクエリレベルで組み合わせることは、DISTINCT
または_DISTINCT ON
_がafter_GROUP BY
_。