web-dev-qa-db-fra.com

Comment calculer les valeurs basées sur la ligne précédente après avoir sauté les 12 premières lignes?

Je cherche de l'aide pour écrire cette requête. J'ai inclus quelques échantillons de données ci-dessous. Ma prémisse initiale est que toutes les valeurs de la 13e rangée terminée seront dynamiques et les 12 premières lignes seront des valeurs statiques. Je connais la formule que je veux calculer chaque valeur de ligne avec.

Ci-dessous est le DDL pour ma vue

CREATE VIEW [v_AMP_C] AS

    SELECT     in.I_Date  ,--Date
               in.I_O_P   ,--Money
               in.I_O_H   ,--Money
               in.I_O_L   ,--Money
               in.I_C_O   ,--Money 
               c.AMPS12_C  --Money
    FROM       dbo.IC_Raw_In in
    INNER JOIN dbo.AMPS12_C c ON in.I_Serial = c.i_serial

et les données sont importées sur cette table en utilisant un insert en vrac dbo.IC_Raw_In Avec type de données d'argent sur toutes les colonnes sauf i_date.

Puis quand j'ai couru cette requête SELECT * FROM v_AMP_C J'ai eu la sortie ci-dessous comme sortie

I_Date   I_O_P     I_O_H    I_O_L    I_C_O     AMPS12_C
01/10/11 509.75    515      508      512.45    512.45
01/10/11 511.7     511.7    506.1499 506.5499  509.4999
01/10/11 507.1499  510.25   507.1499 510.25    509.7499
01/10/11 510       512.3499 509.2999 512.3499  510.3999
01/10/11 512.5     512.5    511.1499 512       510.7199
01/10/11 512.25    512.5    510.1    510.95    510.7583
01/10/11 510.5499  511.7999 510      511.7999  510.9071
01/10/11 511.1     511.85   508.1499 508.8999  510.6562
01/10/11 508.8999  510      508.5    509.95    510.5777
01/10/11 509.8999  509.8999 508.5    508.85    510.4049
01/10/11 509.5     511.2    509      510.5     510.4136
01/10/11 510.5     511.7999 510.1    510.2   **510.3958**
01/10/11 510.2999  511.35   510.25   510.75    510.2541
01/10/11 510.35    512      510.35   510.95    510.6208
01/10/11 510.95    511.7999 510.6    511.1     510.6916
01/10/11 511.0499  511.35   509.1    509.1     510.4208
01/10/11 509.5     509.5    508.1    508.5     510.1291
01/10/11 508.45    508.95   507      507       509.7999
01/10/11 507       508.2    503.2999 503.2999  509.0916
01/10/11 504       505      503.5    504.6499  508.7374
01/10/11 505.45    506.35   504      504.7     508.2999
01/10/11 504.7     505.5    504.2    505.5     508.0208
01/10/11 505.35    505.7    503.1    503.6499  507.4499
01/10/11 504.5     504.5    499.5499 500.5     506.6416
01/10/11 500.45    502      500.25   501       505.8291
01/10/11 501       501.2999 499.5499 500.3999  504.9499
01/10/11 500.45    500.7999 498.6499 498.6499  503.9124
01/10/11 498.7     499.25   498.0499 498.35    503.0166
01/10/11 498.75    499.95   498.7    499       502.2249
01/10/11 499.25    499.6499 498.6499 499.45    501.5957
01/10/11 499.2999  501.1499 499.1    500.8999  501.3957
01/10/11 501.1     502.5    500.5499 502.5     501.2166
01/10/11 502.35    502.95   501      501.5     500.9499
01/10/11 501.5     501.5    500      500.5     500.5333
01/10/11 500       501.35   499.5    499.7999  500.2124
01/10/11 499.95    500.3999 499.2999 500.2999  500.1957
01/10/11 500       501.3999 499.5    499.6499  500.0832
01/10/11 499.7999  501.25   499.6499 500.0499  500.0541

Maintenant, je veux écrire une requête SQL pour obtenir des résultats dans une nouvelle colonne appelée C12wr pour la doute ci-dessous.

Je veux exclure (utilisez NULL) pour les 11 premières lignes dans la colonne C12WR colonne et à la 12e ligne de C12WR colonne "Utilisez une valeur statique qui est dans AMPS12_C (Dans la table ci-dessus montré, la valeur est 510.3958 marquée comme audacieuse). Cette valeur changera à chaque fois que j'importerai les données sur ma table afin que cela change de manière dynamique à chaque fois. Et dans le AMPS12_C Colonne Il doit calculer la formule ci-dessous après la 13e rangée à la fin de la table.

Après la 13e rangée, la colonne C12WR = (la valeur de la rangée ci-dessus (c'est-à-ce que la ligne de rang moyen -1) de la valeur de la ligne de courant C12WR * 11 + de i_c_o colonne)/12

Donc, si je le calcule, il devrait représenter ci-dessus des formules ci-dessous. (Je ne veux pas utiliser de valeurs statiques mais pour l'exemple de cette formule, je prends une valeur statique ici juste pour la facilité d'explication)

= ( 510.3958 * 11 + 510.2 ) / 12

Et après avoir exécuté la requête souhaitée, je devrais obtenir la sortie similaire à celle-ci:

I_Date   I_O_P       I_O_H       I_O_L       I_C_O       AMPS12_C    C12WR
01/10/11 509.75      515         508         512.4500122 512.45      NULL
01/10/11 511.7000122 511.7000122 506.1499939 506.5499878 509.4999    NULL
01/10/11 507.1499939 510.25      507.1499939 510.25      509.7499    NULL
01/10/11 510         512.3499756 509.2999878 512.3499756 510.3999    NULL
01/10/11 512.5       512.5       511.1499939 512         510.7199    NULL
01/10/11 512.25      512.5       510.1000061 510.9500122 510.7583    NULL
01/10/11 510.5499878 511.7999878 510         511.7999878 510.9071    NULL
01/10/11 511.1000061 511.8500061 508.1499939 508.8999939 510.6562    NULL
01/10/11 508.8999939 510         508.5       509.9500122 510.5777    NULL
01/10/11 509.8999939 509.8999939 508.5       508.8500061 510.4049    NULL
01/10/11 509.5       511.2000122 509         510.5       510.4136    NULL
01/10/11 510.5       511.7999878 510.1000061 510.2000122 510.3958333 510.3958333
01/10/11 510.2999878 511.3500061 510.25      510.75      510.2541657 510.3795149
01/10/11 510.3500061 512         510.3500061 510.9500122 510.6208344 510.4103887
01/10/11 510.9500122 511.7999878 510.6000061 511.1000061 510.6916682 510.4553573
01/10/11 511.0499878 511.3500061 509.1000061 509.1000061 510.4208374 510.509078
01/10/11 509.5       509.5       508.1000061 508.5       510.1291707 510.3916554
01/10/11 508.4500122 508.9500122 507         507         509.8000031 510.2340174
01/10/11 507         508.2000122 503.2999878 503.2999878 509.0916697 509.964516
01/10/11 504         505         503.5       504.6499939 508.7375031 509.4091386
01/10/11 505.4500122 506.3500061 504         504.7000122 508.3000031 509.0125432
01/10/11 504.7000122 505.5       504.2000122 505.5       508.0208359 508.6531656
01/10/11 505.3500061 505.7000122 503.1000061 503.6499939 507.450002  508.3904018
01/10/11 504.5       504.5       499.5499878 500.5       506.6416677 507.9953678
01/10/11 500.4500122 502         500.25      501         505.8291677 507.3707539
01/10/11 501         501.2999878 499.5499878 500.3999939 504.9499995 506.8398577
01/10/11 500.4500122 500.7999878 498.6499939 498.6499939 503.9124985 506.3032024
01/10/11 498.7000122 499.25      498.0499878 498.3500061 503.0166651 505.665435
01/10/11 498.75      499.9500122 498.7000122 499         502.2249985 505.0558159
01/10/11 499.25      499.6499939 498.6499939 499.4500122 501.5958328 504.5511646
01/10/11 499.2999878 501.1499939 499.1000061 500.8999939 501.3958333 504.1260686
01/10/11 501.1000061 502.5       500.5499878 502.5       501.2166672 503.857229
01/10/11 502.3500061 502.9500122 501         501.5       500.9499995 503.7441266
01/10/11 501.5       501.5       500         500.5       500.5333328 503.557116
01/10/11 500         501.3500061 499.5       499.7999878 500.212499  503.3023564
01/10/11 499.9500122 500.3999939 499.2999878 500.2999878 500.1958313 503.0104923
01/10/11 500         501.3999939 499.5       499.6499939 500.0833308 502.784617
01/10/11 499.7999878 501.25      499.6499939 500.0499878 500.0541636 502.5233984

édité par : drachenstern ~ j'ai également fusionné les deux questions. Pour @Bestboy ~ Notez le reformatage. Cela devrait aider les gens à comprendre les choses un peu plus rapidement. Cela fait des gens veulent pour vous aider à vous aider un peu plus. ;)

5
user1234

Ce n'est donc pas une bonne réponse, c'est une sorte de réponse de départ pour quelqu'un d'autre à prendre et à préciser cela mieux. Mais je vais faire un coup de poignard.

J'ai d'abord une question: essayez-vous de conserver cela dans une vue? Je ne pense pas que vous puissiez pour ce que vous voulez faire, C'est un peu compliqué, alors examinons les opérations que vous devez faire pour faire ce que vous voulez.

Vous avez déclaré que vous vouliez que les 12 premières lignes soient statiques à chaque fois, et ils devraient toujours avoir leur dernière colonne fixée comme null, et les autres devraient conserver leur valeur. C'est donc une règle d'entreprise que nous devons coder dans SQL. Mais avant de l'encoder en règle générale, demandons s'il y a un moyen de faire en sorte que ces 12 lignes soient les lignes droites à chaque fois. Si nous pouvons faire cette hypothèse, nous pouvons le faire dans le cadre de la prochaine étape.

Votre prochaine exigence est de faire un calcul sur chaque ligne avec la ligne précédente. Étant donné que les 12 premières lignes sont statiques (et je présume non pas calculée), nous n'avons pas à demander "Quoi de la première rangée". Donc, le moyen le plus simple de faire des calculs sur la ligne précédente consiste à attribuer une rownum à chaque ligne, puis utilisez l'ID Rownum dans une comparaison. Ce maillage avec l'exigence précédente.

Nous devons donc commencer par faire notre sélection et attribuer un rownum aussi, comme celui-ci:

SELECT     
    ROW_NUMBER() OVER (ORDER BY in.I_Date) AS rownum,
    in.I_Date  ,--Date
    in.I_O_P   ,--Money
    in.I_O_H   ,--Money
    in.I_O_L   ,--Money
    in.I_C_O   ,--Money 
    c.AMPS12_C  --Money
    CAST(0.0 AS Money) AS C12WR
FROM
    dbo.IC_Raw_In in
INNER JOIN 
    dbo.AMPS12_C c ON in.I_Serial = c.i_serial

Mais pour la façon dont je le ferais, je m'introduisais ces valeurs dans une table Temp, puis utilisez cela pour déterminer ce dont j'ai besoin. De cette façon, vous pouvez simplement vous référer aux colonnes des appels ultérieurs, comme celui-ci:

UPDATE t 
SET C12WR = NULL
FROM temptable t
WHERE t.rownum < 12 -- see how we set the values = null here?

UPDATE t 
SET C12WR = 510.3958
FROM temptable t
WHERE t.rownum = 12 -- see how we set the value to something static? 
                    -- If this were a stored procedure we could use a value passed in here

et puis nous continuons avec:

UPDATE t 
SET C12WR = ( ( t2.C12WR * 11.0 ) + t.I_C_O ) / 12.0
FROM temptable t
INNER JOIN temptable t2 ON t.rownum = (t2.rownum - 1) -- this let's us get the previous row
WHERE t.rownum > 12

Utilisation de cette logique: Après la 13ème ligne, la colonne C12WR = (Prevrow.c12wr * 11 + Currow.I_C_O Colonne)/12

Et puis vous venez de retourner les valeurs que vous vouliez du tentables.

Avis: Les choses que j'ai laissées. Je n'ai pas défini la table Temp, je n'ai pas débarrassé du tentable. Je n'ai pas utilisé la syntaxe appropriée pour l'adressage tentable. Je n'ai rien validé. J'ai présumé que cela allait être utilisé dans une procédure stockée. Je n'ai pas illustré comment utiliser la valeur statique en tant que paramètre de procédure stocké.

J'espère que cela t'aides. J'espère que quelqu'un d'autre aide à faire une meilleure réponse;)

4
jcolebrand