-3
votes

Comment utiliser des fonctions dynamiques dans SQL pour obtenir un modèle de serpent?

J'essaie de prendre des décisions temporelles sur un ensemble de données. Laissez-moi vous expliquer le problème avec une table simple: xxx

Ce que j'essaie de faire est de résumer toutes les variables dans la même période jusqu'à atteindre 5 ou plus que 5. Une fois que j'atteûte Plus de 5, je suis soustraire 5 pour obtenir le reste et je continue à ajouter le reste à la variable suivante dans la prochaine période et ainsi de suite. Pour le résultat indiqué dans le premier total, le chemin sera le suivant: xxx

J'essaie de trouver le chemin et le total pour chaque période.

Ma table est faite verticalement et non horizontalement comme indiqué dans l'exemple. Jusqu'à présent, j'ai eu la cumulative_addition pour toutes les variables utilisant: xxx

mais je ne sais pas si cela devrait être la première étape que je devrais prendre. J'ai également pensé à combiner des fonctions de plomb et de retard dans une requête, mais j'ai alors des problèmes lorsque j'essaie d'incrémenter la période: xxx

donc en 9,76 je devrais faire 9,76- 5 = 4.76 et sauter à 0:05 et en VAR4 pour continuer à ajouter jusqu'à ce que j'ouvre à nouveau 5.

Pensez-vous que je peux résoudre ce problème en utilisant les fonctions de fenêtre?

Merci à l'avance pour votre aide


7 commentaires

Je ne peux pas faire des têtes ou des queues de ce que vous essayez d'accomplir ici. Pouvez-vous essayer d'expliquer cela plus clairement?


Qu'est-ce que ça veut dire? "Ma table est faite verticalement et non horizontalement comme indiqué dans l'exemple."


Je suis juste curieux de savoir «pourquoi»? Cela pourrait éventuellement aider les autres à proposer une solution.


Pourriez-vous fournir DML et DDL pour créer vos échantillons de données. Nous préférerions ne pas avoir à faire le travail supplémentaire pour répondre à votre question.


@Taballeman ma table a le dernier format et non le premier mentionné


@Seanlange je commence à 0:00 et somme Var1 + Var2 + Var3 = 9,76, ce qui est supérieur à 5. Puis je prendrais 4,76 (9,76-5 = 4,76) et je vais continuer à ajouter des valeurs de 0:05 et Var4 jusqu'à ce que Le total est supérieur à 5 encore et ainsi de suite.


Si ce n'est pas un XY Problème Je ne sais pas ce qui est. Ce n'est pas le moyen approprié de traiter des données relationnelles du tout.


4 Réponses :


1
votes

Pas une réponse juste un cas de test comme je le comprends. @zhivab s'il vous plaît commenter. XXX

La tâche est dans chaque TGRP

  • Prenez d'abord (par N) 1..N0 Vals de TsubGrp = 0 jusqu'à la somme Exeeds 5, souvenez-vous N0, (S0 MOD 5)

  • Premier N0..N1 Vals de TsubGrp = 5 jusqu'à (S0 MOD 5) + Sum Exeeds 5 N'oubliez pas N1, (S1 MOD 5)

  • Premier N1..N2 Vals de TsubGrp = 10 jusqu'à (S1 MOD 5) + Sum Exeeds 5

    Obtenez la somme des vals sélectionnés dans chaque TSUBGRP pour le TGRP


1 commentaires

Oui, c'est exactement ce que j'essaie de faire



0
votes

Je suis venu avec une solution mais qu'il martèle des ongles et non que élégant.

Fondamentalement, vous chargez des variables une à la fois et vérifiez si le total est supérieur à 5. S'il y a plus de 5 ans, vous augmentez le TEMPS 5 minutes et soustrayez 5 du calc. xxx

résultats (en raison de données limitées): xxx


1 commentaires

Oui, c'est l'idée méchante. Le problème que j'ai est que j'ai 1 mois de jeu de données (tous les 5 min intervalles pour l'ensemble du mois) et plus de 100 variables (Var1, Var2 ... Var100)



1
votes

Cette réponse fournit une boucle pour les variables et les charge dans une table: xxx

résultats: xxx


3 commentaires

FYI change le moment si vous avez plus de variables. Également si les variables se passent plus de 10, vous devez fixer la distribution à un plus grand varchar.


Je vais essayer cela, il semble que cela fonctionne. Je dois juste stocker le résultat final de l'addition totale dans une variable distincte


C'est dans @total pour que vous puissiez utiliser chaque fois que



0
votes

Un script de Snake Sumping basé sur un ensemble, il pourrait fonctionner plus rapidement, puis une boucle, comme les serpents peuvent se déplacer en parallèle. Amusez-vous.

-- Mock table to visualize groups and subgroups
create table #t(
     [Time] time
    ,Var1 decimal(5,2)
    ,Var2 decimal(5,2)
    ,Var3 decimal(5,2)
    ,Var4 decimal(5,2)
    ,Var5 decimal(5,2)
    ,Var6 decimal(5,2)    
)
insert #t([Time], Var1, Var2, Var3, Var4, Var5, Var6)
values
     -- group 1    
     ('0:00', 1.69, 3.27, 4.80, 2.14, 0.70, 2.14)    
    ,('0:05', 2.73, 2.73, 1.60, 1.20, 0.46, 2.14)    
    ,('0:10', 5.45, 2.69, 4.62, 1.15, 1.03, 4.29)
     -- group 2           
    ,('0:15', 2.07, 4.74, 2.14, 1.50, 0.43, 2.37)    
    ,('0:20', 1.71, 4.62, 1.79, 1.29, 0.73, 2.37)    
    ,('0:25', 1.88, 3.60, 4.00, 2.09, 0.56, 2.25) 
     -- group 3           
    ,('0:30', 5.22, 8.57, 1.54, 2.20, 0.48, 1.13)    
    ,('0:35', 5.00, 5.63, 2.93, 1.32, 1.03, 2.05)    
    ,('0:40', 4.29, 5.29, 5.55, 1.14, 0.38, 1.48); -- this snake will hit the bottom.

-- Task parameters
declare @sumLimit decimal(5,2) = 5.0;
declare @grpStep int = 15; -- minutes
declare @subgrpStep int = 5; -- minutes
declare @nvars int = 6;

-- This is how the real table looks like
with realTable as(
    select [Time], n, val 
    from #t
    cross apply( values (1, Var1), (2, Var2), (3, Var3), (4, Var4), (5, Var5), (6, Var6)) a (n, val )
)
-- How data are grouped, 3 levels tgrp + tsubgrp + n
, grp as(
    select [Time], datediff(MINUTE, '00:00', [Time]) / @grpStep tgrp
         , datediff(MINUTE, '00:00', [Time]) % @grpStep tsubgrp
         , n, val
    from realTable
)
-- Snakes are moving
, snake as (
    select [Time], tgrp, tsubgrp, n, val
        , s = val % @sumLimit
        -- should the snake move down?
        , step = case when val > @sumLimit then @subgrpStep else 0 end
    from grp
    where tsubgrp = 0 and n = 1
    union all
    select grp.[Time], snake.tgrp, grp.tsubgrp, grp.n, grp.val
       , s = cast((s + grp.val) % @sumLimit as decimal(5,2))
       , step = case when s + grp.val > @sumLimit then @subgrpStep else 0 end
    from grp
    join snake on snake.tgrp = grp.tgrp        
       and grp.n = snake.n + 1 -- always move right
       and grp.tsubgrp = snake.tsubgrp + snake.step -- and down when needed
    where grp.n <= @nvars
       and case when s > @sumLimit then snake.tsubgrp + @subgrpStep else snake.tsubgrp end <= @grpStep     
)
-- select * from snake order by tgrp, tsubgrp, n; /*
select min([Time]) gstart, max([Time]) gend, sum(val) [sum]
from snake
group by tgrp
order by tgrp;
-- */


0 commentaires