2016-07-12 1 views
1

Say, j'ai le tableau suivant:requête SQLite pour n-ième jour du mois

CREATE TABLE Data (
    Id INTEGER PRIMARY KEY, 
    Value DECIMAL, 
    Date DATE); 

Depuis l'application est la finance liée, l'utilisateur peut choisir, quel jour serait le premier jour du mois. Par exemple, s'il reçoit un salaire tous les 10 du mois, il peut placer le premier jour du mois à la 10ème place.

Je voudrais créer une requête, qui renvoie la valeur moyenne pour le nième jour du mois, tel que défini par l'utilisateur. Par exemple:

Date   | Value 
---------------+------ 
10.01.2016  | 10 
11.01.2016  | 15 
10.02.2016  | 20 
11.03.2016  | 10 

Résultat de la requête doit être:

Day | Average 
----+-------- 
1 | 15 
2 | 12.5 

Notez que si l'utilisateur fixe premier jour à 10, 9 mois peut être 28, 29, 30 ou 31 jours de un mois (selon le mois dont nous parlons). Donc, ce n'est pas aussi simple que d'extraire le numéro du jour de la date.

+0

Je peux imaginer que cela devienne poilu parce que les différents mois ont un nombre différent de jours. Et pendant quelques mois (par exemple février), le nombre de jours varie avec l'année. –

Répondre

1

En supposant que les valeurs de date n'utilisent pas le format dd.mm.yyyy mais l'un des supported date formats, vous pouvez utiliser le built-in date functions pour le calculer. Pour calculer la différence, en jours, entre deux dates, convertissez-les en un format de date qui utilise des jours en tant que nombre, c'est-à-dire les jours juliens.

Pour obtenir le jour « de base » pour un mois, nous pouvons utiliser les modificateurs:

> SELECT julianday('2001-02-11') - 
     julianday('2001-02-11', 'start of month', '+10 days') + 2; 
2.0 

(Le +2 est nécessaire parce que nous ajoutons au 1er du mois, et non le 0e, et nous comptons commencer à 1, et non 0.)

Si le jour est avant la dixième, la valeur calculée deviendrait nulle ou négative, et nous devons utiliser le mois précédent à la place:

> SELECT julianday('2001-02-09') - 
     julianday('2001-02-09', 'start of month', '-1 month', '+10 days') + 2; 
31.0 

C ombining ces résultats dans cette expression pour calculer la n pour une date Date:

CASE 
WHEN julianday(Date) - 
    julianday(Date, 'start of month', '+10 days') + 2 > 0 
THEN julianday(Date) - 
    julianday(Date, 'start of month', '+10 days') + 2 
ELSE julianday(Date) - 
    julianday(Date, 'start of month', '-1 month', '+10 days') + 2 
END 

Vous pouvez l'utiliser dans votre requête:

SELECT CASE...END AS Day, 
     AVG(Value) AS Average 
FROM Data 
GROUP BY Day; 
0

On dirait que j'ai trouvé en parallèle une autre solution:

SELECT avg(Amount), 
     strftime("%d", Date, "-9 days") AS day 
FROM (
    SELECT sum(Amount) AS Amount, 
     strftime("%Y-%m-%d", Date, "start of day") AS Date 
    FROM Operations 
    GROUP BY strftime("%Y-%m-%d", Date, "start of day") 
) 
GROUP BY day; 

Où "-9 jours" est pour le 10 du mois (donc first_day-1).