SQL查询 - 按另一列排序一组列
Posted
技术标签:
【中文标题】SQL查询 - 按另一列排序一组列【英文标题】:SQL query - order one group of columns by another column 【发布时间】:2021-12-15 14:41:26 【问题描述】:我打算创建一个包含数百万行的表,按以下方式组织:
file,word,occurrences
file23,apples,343<br>
file17,apples,3<br>
file10341,apples,0<br>
...<br>
file16000,apples,0
此表将包含 16,000 个唯一单词,它们在 16,000 个唯一文件中出现。
我想找到一种方法来通过定位特定单词来查询表格,然后只查找最相关的结果 - 即出现次数最多的前 10 个文件。
我尝试了以下代码及其变体,但没有奏效:
WHERE/HAVING `word`=('apples', 'oranges', 'prunes') ORDER BY `occurrences` DESC
话虽如此,我该如何执行此查询,即专门关注相关单词,按出现次数列出它们,并获取前 10-15 个最相关的文件?
【问题讨论】:
帮助我们帮助您并编辑您的问题以包含Minimal, Reproducible Example 但这正是我要问的原因 - 我是 SQL 新手,我不擅长查询表。我弄乱了我发布的代码的 sn-p,我还尝试了 GROUP BY 语句,但无济于事。我已经清楚地描述了我要做什么 - 定位一列“单词”,按另一列“出现”对其进行排序,并获取第三列“文件”的前 10-15 个元素。 `WHERE word IN ('a','b','c') 并在末尾添加 LIMIT 15 【参考方案1】:这就是 FULLTEXT
索引的用途。该表每个文件只有一行,因此只有 16K 行。将有一个 TEXT
列,其中包含该文件中的单词。然后MATCH(col) AGAINST("+apples +oranges" IN BOOLEAN MODE)
将为行提供所有这些单词以及相关性。 (“相关性”并不完全是“发生”。)
如果您选择坚持当前的结构,则“发生次数”没有明确指定。如果一个文件中有 100 个苹果和 20 个橙子怎么办?这是否与每个出现 60 次的文件一样“相关”?是否应该考虑包含“apples”但没有“oranges”的文件?还是所有给定的词都需要出现?
顺便说一句,这是您正在寻找的语法:
`word` IN ('apples', 'oranges', 'prunes')
关于您的数据的问题。 (这可能会影响性能。)有多少“文件”有一个典型的词?通常,有多少个文件包含所有请求的单词?
CREATE TABLE t (
`file` VARCHAR(...) NOT NULL,
`word` VARCHAR(...) NOT NULL,
occurrences INT NOT NULL,
PRIMARY KEY(`word`, `file`),
INDEX(`file`)
) ENGINE=InnoDB;
SELECT `file`, SUM(occurrences) as tot_occ
FROM t
WHERE `word` IN ('apples', 'oranges', 'prunes')
GROUP BY `file`
ORDER BY tot_occ DESC
LIMIT 10;
【讨论】:
绝大多数数据将为 NULL。意思是,绝大多数文件不包含典型的单词,因此,可能不会出现相关性问题,因为大多数单词都分布在文件之间。通常,很少有文件会包含所有单词,因为我手动将 170,000 个单词削减到大约 16,000 个,只保留名词、一些更重要的动词、一些形容词等。大多数“通用”单词都被删除了。 我会坚持我的方法,这似乎更简单,作为一个初学者,但我很欣赏详尽的答案。 用 SUM 代替 AVG。很好的评论。【参考方案2】:使用 Limit 的简单排序应该可以工作。
select file, word, occurrences from yourtable where word in ('apples', 'oranges', 'prunes') ORDER BY occurrences DESC
Limit 10
** 你需要使用 word in ('apples', 'oranges', 'prunes') 代替 word=('apples', 'oranges', 'prunes')
** 由于没有 group by 子句,因此不需要拥有
【讨论】:
以上是关于SQL查询 - 按另一列排序一组列的主要内容,如果未能解决你的问题,请参考以下文章