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

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

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

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

Q&A

解決済

3回答

264閲覧

SQLサーバーで抽出できますでしょうか?

nua

総合スコア18

SQL

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

0グッド

2クリップ

投稿2017/06/25 17:50

###前提・実現したいこと
以下のようなテーブルがあります。
|入出キー|品番|区分|単価1|数量1|単価2|数量2|入出額|差分
|:--|:--:|--:|
|1|N0001|1|141|320|142|220|76360|0
|2|N0001|2|NULL|40|NULL|NULL|5640|0
|3|N0001|1|138|500|NULL|NULL|69000|0
|4|N0001|2|NULL|100|NULL|NULL|14100|0
|5|N0001|2|NULL|200|NULL|NULL|28220|0
|6|N0001|2|NULL|50|NULL|NULL|7100|0
|7|N0001|2|NULL|650|NULL|NULL|90300|0

入出キー :レコード毎にふられている数字
品番 :品物に付けられている番号
区分 :入荷・出荷の区分 1=入荷、2=出荷
単価1 :入荷時の単価1
数量1(区分1の場合):単価1の金額で入荷した数量
数量1(区分2の場合):過去の入荷分(在庫)から出荷した数量
単価2 :入荷時の単価2
数量2(区分1の場合):単価2の金額で入荷した数量
数量2(区分2の場合):過去の入荷分(在庫)から数量1とは違う単価で出荷した数量
入出額 :入荷または出荷した金額
差分 :(単価×数量)と入出額を比較した差分

※品番でGROUP BYしており、品番は全部で10000程あります。

###やりたいこと
品番ごとの各レコードの単価と数量をもとに額を出して、入出額と差分があるものを抽出したいです。

上記の表は、基本的に『(単価1×数量1)+(単価2×数量2)=入出額』のような考え方になります。
ただ、単価に関しては、「先に入荷したものから出荷する」ので、出荷する数量によっては2重の単価になります。
以下に例を記載します。
●入出キー1
(141×320)+(142×220)=76360
●入出キー2
(141×40)=5640 ←単価は入出キー1の単価1で入荷した数量から40個
●入出キー3
(138×500)=69000
●入出キー4
(141×100)=14100 ←単価は入出キー1の単価1で入荷した数量から100個
●入出キー5
(141×180)+(142×20)=28220 ←単価は入出キー1の単価1で入荷した数量から180個。単価1の数量を使い切ったので入出キー1の単価2で入荷した数量から20個
●入出キー6
(142×50)=7100 ←単価は入出キー1の単価2で入荷した数量から50個
●入出キー7
(142×150)+(138×500)=90300 ←単価は入出キー1の単価2で入荷した数量から150個。単価2の数量を使い切ったので、入出キー3の単価1で入荷した数量から500個

区分2(出荷)は、使用されている単価がレコードによって違う場合があるため、『(単価1×数量1)+(単価2×数量2)=入出額』では単純に算出することが出来ません。

Excelにデータを吐き出して抽出しようとしたところ、上長よりSQLで一覧にして欲しいとの指定があり、やり方が思いつきません。
いいやり方はありませんでしょうか?

上記の表は品番は1種類なのですが、実際のデータでは品番ごとにレコード数は1~50レコードほどのデータになっており、レコード数は統一されていません。

###補足情報(言語/FW/ツール等のバージョンなど)
Microsoft SQL Server 2008 R2

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

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

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

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

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

guest

回答3

0

ベストアンサー

SQLパズルのつもりで作成したら、「品番」の部分を失念していました。
時間切れなので、ヒントとして参考になればと回答しておきます。
ただこのSQLを上長に説明するのでしょうか…

手元の SQL Server 2016 で確認。2008では未確認です。

2017/06/27
品番について修正しました。

SQL

1WITH WV AS( 2 SELECT 3 WT.[連番] 4 ,WT.[入出キー] 5 ,WT.[品番] 6 ,WT.[区分] 7 ,WT.[入出額] 8 ,WT.[単価] 9 ,WT.[数量] 10 ,WT.[在庫数] 11 ,WT.[入庫計] 12 ,WT.[出庫計] 13 ,LAG(WT.[入庫計] ,1 ,0) OVER(PARTITION BY WT.[品番] ORDER BY WT.[連番]) AS [L入庫計] 14 FROM 15 ( 16 SELECT 17 MT.[連番] 18 ,MT.[入出キー] 19 ,MT.[品番] 20 ,MT.[区分] 21 ,MT.[単価] 22 ,MT.[数量] 23 ,MT.[入出額] 24 ,SUM(MT.[数量]) OVER(PARTITION BY MT.[品番] ORDER BY MT.[連番]) AS [在庫数] 25 ,SUM( 26 CASE 27 WHEN MT.[数量] > 0 THEN MT.[数量] 28 ELSE 0 29 END 30 ) OVER(PARTITION BY MT.[品番] ORDER BY MT.[連番]) AS [入庫計] 31 ,SUM( 32 CASE 33 WHEN MT.[数量] < 0 THEN - MT.[数量] 34 ELSE 0 35 END 36 ) OVER(PARTITION BY MT.[品番] ORDER BY MT.[連番]) AS [出庫計] 37 FROM 38 ( 39 SELECT 40 ROW_NUMBER() OVER(ORDER BY ZT.[入出キー] ,T.[SEQ]) AS [連番] 41 ,ZT.[入出キー] 42 ,ZT.[品番] 43 ,ZT.[区分] 44 ,CASE 45 WHEN [区分] = 1 THEN T.[数量] 46 WHEN [区分] = 2 THEN - ZT.[数量1] 47 END AS [数量] 48 ,T.[単価] 49 ,ZT.[入出額] 50 FROM 51 [在庫テーブル] ZT 52 LEFT JOIN 53 ( 54 SELECT 55 T1.[SEQ] 56 ,T1.[入出キー] 57 ,T1.[単価] 58 ,T2.[数量] 59 FROM 60 ( 61 SELECT 62 ROW_NUMBER() OVER(ORDER BY [入出キー]) AS [SEQ] 63 ,[入出キー] 64 ,[単価] 65 FROM 66 [在庫テーブル] UNPIVOT([単価] FOR COLNAME1 IN([単価1] ,[単価2])) UP 67 WHERE 68 [区分] = 1 69 ) T1 70 INNER JOIN 71 ( 72 SELECT 73 ROW_NUMBER() OVER(ORDER BY [入出キー]) AS [SEQ] 74 ,[数量] 75 FROM 76 [在庫テーブル] UNPIVOT([数量] FOR COLNAME1 IN([数量1] ,[数量2])) UP 77 WHERE 78 [区分] = 1 79 ) T2 80 ON T1.[SEQ] = T2.[SEQ] 81 ) T 82 ON ZT.[入出キー] = T.[入出キー] 83 ) MT 84 ) WT 85) 86SELECT 87 a.[連番] 88 ,a.[入出キー] 89 ,a.[品番] 90 ,a.[区分] 91 ,a.[入出額] 92 ,a.[単価] 93 ,a.[数量] 94 ,a.[在庫数] 95 ,a.[入庫計] 96 ,a.[出庫計] 97 ,( 98 ( 99 SELECT 100 SUM(b.[数量] * b.[単価]) 101 FROM 102 WV b 103 WHERE 104 b.[連番] <= a.[連番] 105 AND b.[数量] > 0 106 AND b.[品番] = a.[品番] 107 ) - CASE 108 WHEN a.[出庫計] > 0 THEN ISNULL(( 109 SELECT 110 SUM(b.[数量] * b.[単価]) 111 FROM 112 WV b 113 WHERE 114 b.[連番] <= a.[連番] 115 AND b.[数量] > 0 116 AND b.[入庫計] <= a.[出庫計] 117 AND b.[品番] = a.[品番] 118 ) ,0) + ISNULL(( 119 SELECT 120 (a.[出庫計] - b.[L入庫計]) * b.[単価] 121 FROM 122 WV b 123 WHERE 124 b.[連番] = ( 125 SELECT 126 MIN(c.[連番]) 127 FROM 128 WV c 129 WHERE 130 c.[連番] <= a.[連番] 131 AND c.[入庫計] > a.[出庫計] 132 AND c.[品番] = a.[品番] 133 ) 134 ) ,0) 135 ELSE 0 136 END 137 ) AS [金額] 138FROM 139 WV a 140ORDER BY 141 a.[品番] 142 ,a.[連番] 143;

投稿2017/06/26 05:05

編集2017/06/27 00:15
shoko1

総合スコア372

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

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

nua

2017/06/27 01:15

SQL考えてくださってありがとうございます。 作ってくださったものを参考にして書いてみます! 上長には、「作成するの結構大変です」と伝えていますので、成果物として一旦報告し、その上で指示を仰ぎたいと思います。 お時間頂きましたありがとうございました!
guest

0

全体的になにをやりたいかわかりづらいですが
入荷金額に対する、原価計算をしたいならいまの管理方法では無理だと思います

まず品目マスターを用意し、仮想原価をいれておきます(仮に0円でもOK)
次に入荷したタイミングでマスタの原価を修正します。
初回発注については基本的に入荷金額で問題ないでしょう。
2回め以降で、マスタ原価と違う入荷単価の場合
(残在庫マスタ原価+入荷本数入荷単価)/在庫合計で新原価を決めて
マスタの原価を修正します。
出荷時にはマスタの原価を参照して、売上に原価を埋め込み、粗利計算します。

上記方式が常に正しい粗利を計算する方式ですが、実際に出入りが激しい場合
そこまで密に調整はできないと思います。
一般的には移動平均という方式で処理します。

また簡易的にやるために予定単価で全て計算し、適当なマイルストン
例えば、毎月月末や期末ごとに正規原価を振り直し、粗利差異を発生させるのが
会計上の処理になります。

投稿2017/06/26 02:05

yambejp

総合スコア114777

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

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

nua

2017/06/27 01:22

回答ありがとうございます。 質問の書き方が分かりづらくてすみませんでした。 テーブル的に原価計算をメインとした作りになっていないものでは、こういった抽出をするのには難しいんですね・・・
yambejp

2017/06/27 01:34

現場として一つ一つの取引に対して粗利を計算したいのはわかります それを実現するのが入ってきた金額をプールしていく方式か、移動平均です ただ会計的にはそれはあまり意味がなく、入ってきた金額の合計金額と 出ていった金額の合計金額の差が利益になるので経理部門は 全体でしか勘定しません。
guest

0

SQLServerも他のRDBと同様であるとして(SQLServer環境が無いので)、この仕様をSQLだけで実現するにはストアドプロシージャを使う方法が考えられますが、結構、難しいと思います。
先入れ先出のロジックをSQL文で書くのは結構苦労します。さらに入荷データが正規化されていない(単価2を別レコードにすると良い)のもSQL向きでは有りませんし。

Excelにデータを吐き出して抽出しようとしたところ、上長よりSQLで一覧にして欲しいとの指定があり、やり方が思いつきません。

上長さんが、Excelでやろうとされている方に、SQLでと言われる意図は、「SQL+Programの組み合わせ」かもしれませんのでご確認された方が良いと考えます。

投稿2017/06/26 03:12

A.Ichi

総合スコア4070

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

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

nua

2017/06/27 01:20

回答ありがとうございます。 ストアドはあまり得意ではないので、そんな私が書くのは厳しいですね・・・。 上長に確認したところ、他の検証抽出もSQLで行なっているので、全項目を一覧にしたいそうで、excelでやるのは逆に工数が増えて手間になる・・・とのことでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問