- PR -

条件を満たすレコードの合計

投稿者投稿内容
神崎
会議室デビュー日: 2007/07/14
投稿数: 7
投稿日時: 2007-07-14 17:35
はじめて質問させていただきます。
情報に不足などがございましたらご連絡ください。
あと、プレビューで何度も確認して直したのですが、表が崩れて読みにくいかもしれません… (ブラウザの表示フォントによって変わるかもしれません。当方MSPゴシックで表示確認をしております)

使用言語:C#

【取引Dataset】
『取引履歴テーブル』
[取引日][取引先][売価]
01/01 取引先A 1000
01/01 取引先A 3000
01/01 取引先B  500
01/01 取引先C 2000
01/02 取引先A 1000
01/02 取引先D 2000
01/02 取引先D  300
01/03 取引先A 5000
01/03 取引先B 2000



『集計テーブル』
[取引日][取引先A売価合計][取引先B売価合計][取引先C売価合計][取引先D売価合計]
01/01  4000(1000+3000) 500       2000          0
01/02  1000           0         0            2300(2000+300)
01/03  5000           2000       0            0


上記のように【取引Dataset】の『取引履歴テーブル』を『集計テーブル』の形で
取引先ごとに集計したいと思いますが方法が分かりません。

Oracleから『取引履歴テーブル』 を取得し、Datasetの『取引履歴テーブル』にFill
同じく、Oracleの『取引履歴テーブル』からDistinctで重複のない[取引日]を取得し
『集計テーブル』に入れまして、『取引履歴テーブル』と『集計テーブル』でリレーションを作成。その後集計を行うという形で進めております。

DataColumn.Expressionに集約関数SUMを使って
取引先を区別しない日付毎の売価合計でしたら集計できるのですが
そこに「取引先毎に(取引先Aの…等)」という条件を付加できずにいます。

「条件を満たすレコードの合計」を集計できれば可能なのだと思いますが、
その方法をご教授願えませんでしょうか?

Excelを使う場合、SUMIF関数などを使って集計が可能ですが、そのような集約関数はないですし…
よっし〜。
ベテラン
会議室デビュー日: 2007/04/17
投稿数: 89
お住まい・勤務地: 北のほうの国
投稿日時: 2007-07-14 18:03
リレーションを作成というのが私にはわかりませんが。

[取引日][取引先]でGROUP BY&SUMをクエリ内で行ってから
取引履歴テーブルを取得する、ではダメなのでしょうか?
神崎
会議室デビュー日: 2007/07/14
投稿数: 7
投稿日時: 2007-07-15 10:37
ご返答ありがとうございます。

DataSet中のいくつかのテーブル間でリレーションを設定し
親テーブルと子テーブルを作ってDataCoulmn.Expressionプロパティに集約関数を入れる…
という方法を書籍で見てやっているのですが、
通常そのような方法は採らないものなんでしょうか?

一旦一覧のような全データをDataSetに取り込んでそれをDataViewや集約関数などを使って後付で加工していく方法をとっているのですが…

で、アドバイスどおりGROUP BYとSUMを使ってSQLでのデータ取得に挑戦してみたのですが、
当方SQLも不勉強でして、取引先Aだけを日付ごとに集計など、
最初の表で言うと[取引日]と[取引先A売価合計]の一列分だけだったら取得できるのですが、同時に[取引先B売価合計]も[取引先C売価合計]も取得が出来ませんでした。

とりあえず作ってみたSQL分が
SELECT 取引日,SUM(売価) FROM 取引履歴テーブル WHERE 取引先=取引先A GROUP BY 取引日

という感じだったのですが、取引先B以降の列をどうして良いか分からず、とりあえず範囲の苦肉の策でUNIONで繋げて

SELECT 取引日,SUM(売価) FROM 取引履歴テーブル WHERE 取引先=取引先A GROUP BY 取引日 UNION SELECT 取引日,SUM(売価) FROM 取引履歴テーブル WHERE 取引先=取引先B GROUP BY 取引日

…としてみました。しかし、これでは売価合計列に取引先Aの合計と取引先Bの合計が混入する形となり、やはり上手く行きませんでした。


良いやり方を教えていただけると助かります。
よろしくお願いします。
七味唐辛子
ぬし
会議室デビュー日: 2001/12/25
投稿数: 660
投稿日時: 2007-07-15 13:12
根本の原因は集計テーブルにありますが?
ほんとうに必要なんですか?

UNION大作戦ですが 合計が混入するするのは、取引先をわけていないためです。

SELECT 取引日,取引先SUM(売価) 以下略
でうまくいきませんか
神崎
会議室デビュー日: 2007/07/14
投稿数: 7
投稿日時: 2007-07-15 19:59
ご返答ありがとうございます。

本日は帰宅が遅くなるので、手短に。
実はこの根本原因の集計テーブルは、説明用に簡略化してお伝えしてますが、
実はもっとどうしようもない「入庫」も「出庫」も「販売」も一緒くたの表なのです…

ですが、すでに出来上がっている表なので、これに向き合い戦っていかなくてはならないのですorz

UNIONを使う発想は間違ってはいないのに、使い方が良くない…と言うことなのですね?
もう少し詳しく教えていただけるとありがたいのですが、とりあえず自分で調べてみます。

成果が上がるか音を上げたらまたご連絡します。

それまでの間、回答者様をはじめ、どなた様もよろしければ良い方法を書いておいていただけましたら、私はとても楽をさせていただけますので、よろしくお願いします。
べる
ぬし
会議室デビュー日: 2003/09/20
投稿数: 1093
投稿日時: 2007-07-16 01:19
取引履歴テーブルから集計テーブルを作りたい、ってことでいいんですよね?

SUMの中を工夫すればいいんだと思います。

SELECT 取引日
,SUM(CASE WHEN 取引先 = '取引先A' THEN 売価 ELSE 0 END) AS 取引先A
,SUM(CASE WHEN 取引先 = '取引先B' THEN 売価 ELSE 0 END) AS 取引先B
・・・
FROM 取引履歴テーブル GROUP BY 取引日

要するに「クロス集計」がしたい、ということだと思います。
オラクルに詳しくないので、このキーワードでさがせばもっといい方法が見つかるかもしれませんが、
SQL SERVERの時は上記のようにしてました。全部の取引先がわかっているときはベタに書いてもいいし、
わからないときは、一回クエリ投げて、プログラム上で動的にSQLを作る感じですかね。

もっとも、これはSQLでどうにかする方法であって、SQLではとりあえずGROUP BYせずに取ってきて
C#の方でDataSetのテーブルに動的にカラム追加したりしてどうにかする方法も考えられますけどね。
神崎
会議室デビュー日: 2007/07/14
投稿数: 7
投稿日時: 2007-07-16 01:44
ご返答ありがとうございます。

検索に使えそうなキーワードをいっぱい戴きました。
ありがとうございます。

[クロス集計]・[プログラム上で動的にSQLを作る]など、
今の私の持ち物にはない知識がいっぱいですが、楽しんで勉強できそうです。

>C#の方でDataSetのテーブルに…
これが出来れば、既存のコードの書き換えが少なくて済みそうなんですが…
こちらのほうは正直現在の私の検索力ではお手上げに近いですorz
べる
ぬし
会議室デビュー日: 2003/09/20
投稿数: 1093
投稿日時: 2007-07-16 05:10
引用:
>C#の方でDataSetのテーブルに…
これが出来れば、既存のコードの書き換えが少なくて済みそうなんですが…
こちらのほうは正直現在の私の検索力ではお手上げに近いですorz

どちらかというとマニュアルを見る話なので、検索してもあまりズバリなソースにありつけないと
思いますが一応サンプルとしては、
http://msdn2.microsoft.com/ja-jp/library/hfx3s9wd(VS.80).aspx

「Oracleから『取引履歴テーブル』 を取得し、Datasetの『取引履歴テーブル』にFill」
↑このテーブルのレコードを1行ずつ見てって、既知でない取引先が出現したら、
集計テーブル.Columns.Add
ってしてカラムを足して、該当日付のレコードに売価をセット。
既知だったら該当日付のレコードの該当取引先カラムに加算すればいいですよね。

ただ、結構コードは書くことになると思います。
クロス集計するだけなのでしたら、個人的にはSQLで解決の方が好きです。
集計テーブルにFillするときのSQLをさっきのSQLにすればいいだけですから。

スキルアップ/キャリアアップ(JOB@IT)