Comme Elliott a mentionné - « il est généralement plus difficile d'expliquer les fonctions analytiques aux nouveaux utilisateurs » et même les utilisateurs établis ne sont pas toujours 100% bons (tout en étant très très proche)!
Ainsi, alors que la réponse de Dudu Markovitz est grande - malheureusement, elle est toujours incorrecte (au moins selon la façon dont j'ai compris la question). Le cas où ce n'est pas correct quand vous avez plusieurs tâches commencé à la start_time - de sorte que ces tâches ont mal « tâches en cours d'exécution » résultat
À titre d'exemple - traiterai exemple:
task_id start_time end_time
a 1 10
aa 1 2
aaa 1 8
b 2 5
c 5 15
d 8 13
e 12 20
f 21 30
Je pense , vous attendez ci-dessous résultat:
task_id start_time end_time running_tasks
a 1 10 3 # a,aa,aaa
aa 1 2 3 # a,aa,aaa
aaa 1 8 3 # a,aa,aaa
b 2 5 3 # a,aaa,b (aa has ended)
c 5 15 3 # a,aaa,c (b has ended)
d 8 13 3 # a,c,d (aaa has ended)
e 12 20 3 # c,d,e (a has ended)
f 21 30 1 # f (c,d,e have ended)
Si vous essayez avec le code de Dudu - vous obtiendrez ci-dessous à la place
task_id start_time end_time running_tasks
a 1 10 1
aa 1 2 2
aaa 1 8 3
b 2 5 3
c 5 15 3
d 8 13 3
e 12 20 3
f 21 30 1
Comme vous pouvez voir le résultat pour les tâches a et aa mal.
La raison est en raison de l'utilisation de ROWS UNBOUNDED PRECEDING
au lieu de RANGE UNBOUNDED PRECEDING
- petite mais très importante nuance!
donc ci-dessous requête vous donnera un résultat correct
SELECT task_id,start_time,end_time,running_tasks
FROM (
SELECT
task_id, tm, op, start_time, end_time,
SUM(op) OVER (ORDER BY tm ,op RANGE UNBOUNDED PRECEDING) AS running_tasks
FROM (
SELECT
task_id, start_time AS tm, 1 AS op, start_time, end_time
FROM tasks UNION ALL
SELECT
task_id, end_time AS tm, -1 AS op, start_time, end_time
FROM tasks
) t
)t
WHERE op = 1
ORDER BY start_time
résumé rapide:
RANGS UNBOUNDED PRÉCÉDANT - définit le cadre de la fenêtre en fonction de la position de lignes
tandis que
GAMME UNBOUNDED PRÉCÉDANT - définit le cadre de la fenêtre basé sur les valeurs des lignes
Encore une fois - comme Elliott l'a mentionné - il est beaucoup plus complexe d'y entrer que le concept JOIN - mais il en vaut la peine (car il est beaucoup plus efficace han rejoint) - voir plus sur Window Frame Clause et ROWS vs RANGE utiliser
Dudu, merci - solution intelligente, et il résout l'exemple simplifié spécifique. J'espérais obtenir une solution plus généralisée où la fonction de fenêtre pourrait être conditionnée sur la ligne actuelle - est-ce possible? –
@NewDev, je ne comprends pas votre intention s'il vous plaît fournir un exemple. –
Est-il possible de 'COUNT' sur une fonction de fenêtre avec une condition pour ne compter que les lignes qui satisfont une condition par rapport à la ligne courante.Par exemple, si la ligne actuelle est 'start_time = 8', la fonction de la fenêtre ne peut-elle compter que les lignes dont' end_time> 8' et 'start_time <= 8'? –