- PR -

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

投稿者投稿内容
よねKEN
ぬし
会議室デビュー日: 2003/08/23
投稿数: 472
投稿日時: 2007-07-16 11:53
引用:

神崎さんの書き込み (2007-07-16 01:44) より:
>C#の方でDataSetのテーブルに…
これが出来れば、既存のコードの書き換えが少なくて済みそうなんですが…



ExpressionプロパティでもSQLのCase文相当のことはできますよ。
IIF関数です。詳細はヘルプをご覧ください。

引用:

こちらのほうは正直現在の私の検索力ではお手上げに近いですorz



検索する前にヘルプの確認ですね。
DataColumn.Expressionプロパティのヘルプに使える機能は全部載っています。
神崎
会議室デビュー日: 2007/07/14
投稿数: 7
投稿日時: 2007-07-18 19:54
毎度皆様ご返答ありがとうございます。

Caseを使って各取引先毎にSQLで一覧を作るところまでは成功しました。

後は、IIFを使ってDataset上で上手いコトやれるかの実験を行ってみて、
どちらのほうが効率がいいかを考察してみます。

どうもありがとうございました。
神崎
会議室デビュー日: 2007/07/14
投稿数: 7
投稿日時: 2007-07-19 12:33
[IIF]を使ってみる実験を行ったのですが…

SUM(IIF(Child.取引先='取引先A',Child.売価,0))
と列のExpressionプロパティに入れてみたのですが、

[集約引数の構文エラー : 可能な 'Child' 修飾子を含む単一列の引数を指定してください。]
と、怒られてしまいます。

色々と「なぜ怒られるのか」を考えてみたのですが、
エラーの直接の意味を
「SUMの中では"結果的に[Child.列]のような引数"にならなければいけないのに、
IIFのfalseで返ってきた引数で考えるとSUM(0)みたいになるからダメ」
だと思ったのですが、
試しに
SUM(IIF(Child.取引先='取引先A',Child.売価,Child.売価))

みたいにしても、まったく同じエラーで怒られます。
…と考えると、もう、エラーの直接の意味を
「SUMの中では"結果じゃなくて[Child.列]のような引数としか書いちゃダメ"IIFはSUMの中に書いたらダメ」
と解釈するより他になくなってしまい…。

IIFとSUMの入れ子の書き方がおかしいのでしょうか…
Expressionプロパティのヘルプには
個別の解説は載っていても、組み合わせた使い方の実例が見当たらず、
暗礁に乗り上げております…
よねKEN
ぬし
会議室デビュー日: 2003/08/23
投稿数: 472
投稿日時: 2007-07-19 13:34
IIF関数は使ったことがあったので書いたのですが、
申し訳ありません。SUMとIIFを組み合わせることは簡単にはできなさそうですね。

引用:

「SUMの中では"結果じゃなくて[Child.列]のような引数としか書いちゃダメ"IIFはSUMの中に書いたらダメ」
と解釈するより他になくなってしまい…。



1. IIFの結果を保持する列を用意する
2. IIFの結果の列をSUMする列を用意する

とすることで、合計を算出することはできると思いますが、
その後、「集計テーブル」の表示形式に加工するには、
さらにいろいろな工夫をする必要がありそうです。

#集計結果を表示するにはその行を表示するかどうかを判定できる条件のダミー列を用意しておいて
#DataViewのRowFilterプロパティで表示行を絞り込めばできなくはないと思うのですが、
#プロパティ設定だけでは無理っぽい

IIF関数を提案しておいて何ですが、今回の要件には
SQLで対応した方がよさそうです。

調査していたら、こんな過去スレが・・・↓
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=34069&forum=7&start=8&10
べる
ぬし
会議室デビュー日: 2003/09/20
投稿数: 1093
投稿日時: 2007-07-20 18:47
「リレーションを作成」の意味がようやくわかりました。C#側でオブジェクト同士が親子関係を持ってるのですね。
あまりこういうことをやったことがないのでイメージできてませんでした。

引用:
1. IIFの結果を保持する列を用意する
2. IIFの結果の列をSUMする列を用意する

結果的にはこの方法でどうにかできるようです。

コード:
        SqlDataAdapter adapter = new SqlDataAdapter("select 取引日,取引先,売価 
                from 取引履歴テーブル ", connectionString);
        SqlDataAdapter adapter2 = new SqlDataAdapter("select distinct 取引日 
                from 取引履歴テーブル ", connectionString);
        DataSet ds = new DataSet("ds1");
        adapter.Fill(ds, "table1");
        adapter2.Fill(ds,"distinct");

        ds.Tables["distinct"].ChildRelations.Add(ds.Tables["distinct"].Columns["取引日"],
                 ds.Tables["table1"].Columns["取引日"]);

        foreach (DataRow row in ds.Tables["table1"].Rows)
        {
            string name = (string)row["取引先"];
            //既知の取引先でない場合カラムを追加
            if (!ds.Tables["table1"].Columns.Contains(name))
            {
                DataColumn colsum = new DataColumn(name, typeof(int));
                colsum.Expression = "IIF( 取引先='" + name + "' , 売価 , 0 )";
                ds.Tables["table1"].Columns.Add(colsum);

                DataColumn col1 = new DataColumn(name);
                col1.Expression = "Sum(Child." + name + ")";
                ds.Tables["distinct"].Columns.Add(col1);
            }
        }


ds.Tables["table1"]が取引履歴テーブルをそのままFillしたテーブルです。
ds.Tables["distinct"]が、『取引履歴テーブル』からDistinctで重複のない[取引日]を取得したテーブルです。
Fillするときはカラムは取引日だけで、そこに動的にカラムを追加していってます。

追加するカラムの定義自体が「そういう値を持ったレコードが存在するかどうか」なので
どうしてもこういうコードになっちゃうでしょうね。

SQLで処理するのとどっちがスマートかは、場合によるというかその人の好みにもよりそうです。
神崎
会議室デビュー日: 2007/07/14
投稿数: 7
投稿日時: 2007-07-20 19:00
お返事ありがとうございます。

やはりSUMとIIFを使って一撃で…というわけには行かないのですね。
Excelでは複雑な数式を作るときに先に一時的な集計列を作って後でまとめて参照…
なんてコトを良くするのですが、Expressionでそれをするのは私には複雑みたいです。

やはりSQLでやるのが一番スマートなように思えますのでそうやってみます。

この件に関しては、後は自分で頑張ってみます。
お付き合いいただいた皆様どうもありがとうございました。

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