Ma base de données (sqlite3) comporte deux tables avec les schémas suivants :
CREATE TABLE log(d date, usr text, tag text, bytes int);
CREATE TABLE valid(tag text, filesize int);
Supposons que j'ai les données d'exemple suivantes :
d | usr | tag | bytes
--------------------------------
2012-01-19 | bob | foo | 990
2012-01-18 | bob | foo | 1000
2012-01-17 | joe | bar | 2000
2012-01-16 | joe | bar | 1800
2012-01-15 | joe | baz | 0
tag | size
-----------
foo | 1000
bar | 2000
J'aimerais obtenir une liste des événements les plus récents qui ont conduit à un utilisateur ne pouvant pas accéder à tous les octets d'un fichier valide. Dans l'exemple ci-dessus, la sélection devrait renvoyer 2012-01-19 | bob | foo | 990.
Actuellement, j'utilise deux instructions SELECT pour obtenir les résultats. La première obtient l'événement le plus récent par utilisateur, et la seconde vérifie si tous les octets ont été consultés.
CREATE VIEW tmp AS
SELECT * FROM log JOIN (SELECT max(d) AS maxd, usr FROM log GROUP BY usr) AS
tmplog ON (tmplog.usr=log.usr and tmplog.maxd=log.d);
SELECT usr,d FROM tmp
WHERE tag IN (SELECT tag FROM valid) AND bytes NOT IN (SELECT size FROM valid);
Y a-t-il un moyen de faire cela avec une seule SELECT ou de manière plus efficace ?
Mise à jour :
Dans l'exemple ci-dessus, la requête ne devrait pas récupérer l'utilisateur "joe" car sa dernière entrée de journal montre un accès complet à un fichier.