質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

0回答

819閲覧

【SQL】移動平均の算出について

hoshiimohunda

総合スコア15

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

0クリップ

投稿2019/03/20 13:41

■環境

SQL Server2016(MicrosoftのSQL)

■やりたいこと

日付金額
2019/1/1500
2019/2/11000
2019/3/11500

例えば上記のようなテーブルがあった場合に、
2行目は
(500 + 1000) / 2 = 750
3行目は
(750 + 1500) / 2 = 1125
といったように、1行前の計算結果を基に移動平均を算出したいです。(1125を取得したいです)

最適な方法が見つからず、質問をさせて頂きました。
お手数ですが、何か良い方法があれば教えて頂ければと思います。

■補足(これはNG)

よく移動平均と聞くとWindow関数を使った解法が見つかりますが、
今回は「1行前の計算結果を基に移動平均を算出したい」のでNGです。

SELECT TOP 1 AVG(金額) OVER(ORDER BY 日付 ASC) AS 結果 FROM 仕入 ORDER BY RANK() OVER(ORDER BY 日付 ASC) DESC

※結果は1000

■現状考えている案

○案1(カーソルを使って回す)

DECLARE crTriggerList CURSOR FOR SELECT 金額, RANK() OVER(ORDER BY 日付 ASC) AS RK FROM 仕入 ORDER BY RK ASC DECLARE @金額 decimal DECLARE @RK bigint DECLARE @結果 decimal OPEN crTriggerList; FETCH NEXT FROM crTriggerList INTO @金額, @RK WHILE @@FETCH_STATUS = 0 BEGIN IF (@RK = 1) SET @結果 = @金額 ELSE SET @結果 = (@金額 + @結果) / 2 FETCH NEXT FROM crTriggerList INTO @金額, @RK; END CLOSE crTriggerList; DEALLOCATE crTriggerList; SELECT @結果 AS 結果

○案2(RANK付けした内容を一次テーブルに書き込んだうえ、再帰クエリで回す)

SELECT 日付, 金額, RANK() OVER(ORDER BY 日付 ASC) AS RK INTO #HOGE FROM 仕入; with [CTE] ([日付], [金額],[RK]) as ( SELECT 日付, 金額, RK FROM #HOGE WHERE RK = 1 UNION ALL SELECT 日付, 金額, RK FROM ( SELECT HOGE.日付, CONVERT(decimal, (HOGE.金額 + [CTE].金額) / 2) AS 金額, HOGE.RK FROM #HOGE AS HOGE INNER JOIN [CTE] ON HOGE.RK = [CTE].[RK] + 1 )AS HUGA ) SELECT 金額 AS 結果 FROM [CTE] WHERE RK IN(SELECT MAX(RK) FROM [CTE])

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ikedas

2019/03/20 23:16

そもそも、おっしゃるような「1行前の計算結果を基に」算出するものは「移動平均」ではないと思うのですが……。最初の列からあとのすべての列の値をもとに算出していることになるので、平均値を取る範囲が移動していませんよね。
hoshiimohunda

2019/03/21 01:26

ikedas

2019/03/21 05:01

簡単なほうの解説をさわりだけ読みました。平均原価をここで説明している移動平均法で算出したいのですね。 ・ご質問の説明だと入庫 (受入というのかな?) だけを考慮して出庫 (払出?) を考慮していないことになりませんか。 ・各行ごとの入出庫数量がわからないと平均原価はだせないのでは。
hoshiimohunda

2019/03/21 05:09

コメントを有難うございます。 厳密には記載いただいた受払数量も考慮致します。 ここでは二行目の計算結果を三行目で使うような手法について知りたかったので、計算式は簡略化させていただきました。 紛らわしくてすみません。
ikedas

2019/03/21 05:36

前回の平均原価だけあっても在庫総額と在庫数はわからないですよね。つまり、ご質問の計算方法自体がまちがっているので、結果の「1125」という数値は無意味です。まちがった方法を前提に質問されても、正確な回答は得られないとおもいます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問