Sqlite 对组合键的相对补充
Sqlite relative complement on combined key
首先介绍一下我的问题的背景:
我正在做一个爬虫,我想监控一些高分列表。
高分列表由两个参数定义:类别和集合(一起唯一)。
成功下载后,我创建了一个新的统计条目(类别、集合、createdAt,...)
问题:我只想每天查询一次高分榜单。所以我需要一个查询,该查询将 return 24 小时内未下载的类别和集合。
应该使用统计数据 Table。
我有一个包含所有可能类别和所有可能集合的列表。它们像交叉连接一样工作。
所以基本上我需要交叉连接的相对补充与最近 24 小时的条目
我的想法:交叉连接类别和集合以及 'substract' 过去 24 小时内创建的所有 Pair(category, collection) 统计条目
问题 1:是否可以在查询中定义类别和集合并交叉连接它们,或者我是否必须为它们创建一个 table?
问题2:我的Idea是正确的做法吗?你会如何在 Sqlite 中执行此操作?
好的,我意识到这听起来可能令人困惑,所以我画了一幅我真正想要的图像。
我对 C 感兴趣
这是我当前在 java 中的代码,也许它有助于理解问题:
public List<Pair<String, String>> getCollectionsToDownload() throws SQLException {
long threshold = System.currentTimeMillis() - DAY;
QueryBuilder<TopAppStatistics, Long> query = queryBuilder();
List<TopAppStatistics> collectionsNotToQuery = query.where().ge(TopAppStatistics.CREATED_AT, threshold).query();
List<Pair<String, String>> toDownload = crossJoin();
for (TopAppStatistics stat : collectionsNotToQuery) {
toDownload.remove(new Pair<>(stat.getCategory(), stat.getCollection()));
}
return toDownload;
}
private List<Pair<String, String>> crossJoin() {
String[] categories = PlayUrls.CATEGORIES;
String[] collections = PlayUrls.COLLECTIONS;
List<Pair<String, String>> toDownload = new ArrayList<>();
for (String ca : categories) {
for (String co : collections) {
toDownload.add(new Pair<>(ca, co));
}
}
return toDownload;
}
解决您问题的最简单方法是 EXCEPT。假设你有一个子查询
一个计算 A,另一个计算 B。这些查询
可能非常复杂。关键是两者应该 return 相同的列数和可比较的数据类型。
在 SQLite 中你可以这样做:
<your subquery 1> EXCEPT <your subquery 2>
就这么简单。
例如:
SELECT a, b FROM T where a > 10
EXCEPT
SELECT a,b FROM T where b < 5;
记住,两个子查询必须return相同的列数。
首先介绍一下我的问题的背景:
我正在做一个爬虫,我想监控一些高分列表。
高分列表由两个参数定义:类别和集合(一起唯一)。
成功下载后,我创建了一个新的统计条目(类别、集合、createdAt,...)
问题:我只想每天查询一次高分榜单。所以我需要一个查询,该查询将 return 24 小时内未下载的类别和集合。
应该使用统计数据 Table。
我有一个包含所有可能类别和所有可能集合的列表。它们像交叉连接一样工作。
所以基本上我需要交叉连接的相对补充与最近 24 小时的条目
我的想法:交叉连接类别和集合以及 'substract' 过去 24 小时内创建的所有 Pair(category, collection) 统计条目
问题 1:是否可以在查询中定义类别和集合并交叉连接它们,或者我是否必须为它们创建一个 table?
问题2:我的Idea是正确的做法吗?你会如何在 Sqlite 中执行此操作?
好的,我意识到这听起来可能令人困惑,所以我画了一幅我真正想要的图像。
我对 C 感兴趣
这是我当前在 java 中的代码,也许它有助于理解问题:
public List<Pair<String, String>> getCollectionsToDownload() throws SQLException {
long threshold = System.currentTimeMillis() - DAY;
QueryBuilder<TopAppStatistics, Long> query = queryBuilder();
List<TopAppStatistics> collectionsNotToQuery = query.where().ge(TopAppStatistics.CREATED_AT, threshold).query();
List<Pair<String, String>> toDownload = crossJoin();
for (TopAppStatistics stat : collectionsNotToQuery) {
toDownload.remove(new Pair<>(stat.getCategory(), stat.getCollection()));
}
return toDownload;
}
private List<Pair<String, String>> crossJoin() {
String[] categories = PlayUrls.CATEGORIES;
String[] collections = PlayUrls.COLLECTIONS;
List<Pair<String, String>> toDownload = new ArrayList<>();
for (String ca : categories) {
for (String co : collections) {
toDownload.add(new Pair<>(ca, co));
}
}
return toDownload;
}
解决您问题的最简单方法是 EXCEPT。假设你有一个子查询 一个计算 A,另一个计算 B。这些查询 可能非常复杂。关键是两者应该 return 相同的列数和可比较的数据类型。
在 SQLite 中你可以这样做:
<your subquery 1> EXCEPT <your subquery 2>
就这么简单。
例如:
SELECT a, b FROM T where a > 10
EXCEPT
SELECT a,b FROM T where b < 5;
记住,两个子查询必须return相同的列数。