2016-10-29 1 views
1

Tout d'abord un peu d'arrière-plan sur mon problème:
Je construis un crawler et je veux surveiller certaines listes de meilleurs scores.
Les listes de meilleurs scores sont définies par deux paramètres: une catégorie et une collection (ensemble unique).
Après un téléchargement réussi, je crée une nouvelle entrée de statistiques (catégorie, collection, createdAt, ...)complément relatif Sqlite sur la clé combinée

Problème: Je ne souhaite interroger la liste des meilleurs scores qu'une seule fois par jour. J'ai donc besoin d'une requête qui retournera la catégorie et la collection qui n'ont pas été téléchargées dans 24h. Le tableau de statistiques devrait être utilisé pour cela.
J'ai une liste de toutes les catégories possibles et de toutes les collections possibles. Ils fonctionnent comme une jointure croisée. Donc, fondamentalement, j'ai besoin du complément relatif de la croix rejoindre les entrées des dernières 24h

Mon Idée: Croix joindre des catégories et des collections et «soustraire» tous Pair (catégorie, collection) des entrées de statistiques qui a été créé pendant dernier 24 h

Question 1: Est-il possible de définir des catégories et des collections à l'intérieur de la requête et de les rejoindre ou dois-je créer une table pour eux?

Question 2: Mon idée est-elle la bonne approche? Comment feriez-vous cela en Sqlite? Ok, je me rends compte que cela peut sembler confus donc j'ai dessiné une image de ce que je veux réellement. enter image description here

Je suis intéressé par C.

Voici mon code actuel en java, peut-être il aide à comprendre le problème:

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; 
} 

Répondre

1

La solution la plus simple à votre problème est un SAUF. Supposons que vous ayez une sous-requête qui calcule A et une autre qui calcule B. Ces requêtes peuvent être très complexes. La clé est que les deux doivent renvoyer le même nombre de colonnes et de types de données comparables.

Dans SQLite vous pouvez alors faire:

<your subquery 1> EXCEPT <your subquery 2> 

Aussi simple que cela.

Par exemple:

SELECT a, b FROM T where a > 10 
EXCEPT 
SELECT a,b FROM T where b < 5; 

Rappelez-vous, les deux sous-requêtes doivent retourner le même nombre de colonnes.