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

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

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

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

SQL

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

Q&A

解決済

3回答

12242閲覧

SQLのCOUNT関数について

pro-poke5

総合スコア46

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

SQL

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

0グッド

1クリップ

投稿2016/08/26 01:35

編集2016/08/26 01:36

VS2016
.Netframework4.6

こんにちわ
sqlについて質問です

sqlのCount関数を使ってたくさんあるテーブルごとのなかの同じカラムにそれぞれ種類別の番号があるのですが、その番号を集計し有無を調べ、その有無でC#(別ファイル)で出力するというものです(わかりづらくてすみません)

sqlでカウントした値?を何かに代入しその代入した値(集計した数が無しなら"0"、1つでもあるなら"2")でif文などで判断させたいです。

sqlでカウントされた集計結果の使い方がわかりません

アドバイスお願いいたします。

SQL

1sql.Append("select * count from alertatble where alert = 32,02,13 "); 2sql.Append("select * count from alertatble where alert = 33,03,10"); 3sql.Append("select * count from alertatble where alert = 35,05,15");

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

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

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

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

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

Panzer_vor

2016/08/27 15:21 編集

もう少し要件に踏む込んだ確認をさせてください。 1. 質問文のコードではCOUNTを利用しておりますが、データ有無のチェックができればそもそもレコード件数は取得する必要はないということでしょうか? 2. 念のため確認です。「たくさんあるテーブル」と記載がありますが、そのいずれのテーブルも同じカラム(種類番号)を保持しているという認識で問題ないでしょうか? 3. ファイル出力とあるので恐らくそうかと思いますが、各テーブルの内容の取得も行いたいという認識で合ってますでしょうか? 後、可能ならばフラグとデータ有無フラグとデータ取得を同タイミングで行いたいとかありますでしょうか? (修正依頼での改行の仕方が分からず、見辛くすみません。スマホがあかんのかな・・・)
pro-poke5

2016/08/29 05:03

ありがとうございます 1.データの有無がチェックできれば件数自体はどうでもいいです。 2.はい、そちらの認識であっています。たくさんテーブルがありそれぞれ同じ種類(名前)のデータをとってきて・・・という感じです 3.内容の取得も行いたいです。番号がそれぞれあって最終的にその番号でswich文により記号で出力させるものです
guest

回答3

0

こんなSQLも書けます

sql

1select sum(case when alert in (32,02,13) then 1 else 0 end) as count1, 2 sum(case when alert in (33,03,10) then 1 else 0 end) as count2, 3 sum(case when alert in (35,05,15) then 1 else 0 end) as count3 4from alertatble;

表題はCOUNTでした。

sql

1select count(case when alert in (32,02,13) then 0 else null end) as count1, 2 count(case when alert in (33,03,10) then 0 else null end) as count2, 3 count(case when alert in (35,05,15) then 0 else null end) as count3 4from alertatble;

投稿2016/08/26 03:06

編集2016/08/26 03:21
A.Ichi

総合スコア4070

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

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

0

ベストアンサー

始めに、まだ要件を勘違いしていたらすみません^^;

質問者さんのやりたいことを踏まえると、
すぐに思いつく範囲では2つほどアプローチ方法があるのかなと思われます。

DB通信は増えるがSQL、C#側のコードをシンプルに済ます作戦

こちらは単純なアプローチで、
それぞれの条件グループ(掲示コードのalert = 32,02,13などの箇所)ごとにSQLを発行するというものです。
その際のSQLのイメージは下記のようなイメージです。

SQL

1SELECT 2 T.* 3FROM 4 ( 5 SELECT 6 A.NAME AS NAME 7 , A.ALERT AS ALERT -- 種別番号 8 , A.HOGE AS HOGE 9 FROM 10 TABLE_A A 11 UNION ALL -- ※取得レコードに重複が発生する場合は「UNION」の方が良いか? 12 SELECT 13 B.NAME 14 , B.ALERT -- 種別番号 15 , B.HOGE 16 FROM 17 TABLE_B B 18 ) T 19WHERE 20 T.ALERT IN (32,02,13)

上記のようなクエリを条件を差し替えて実行するというのが、
このアプローチの手法です。

ただし、条件グループごとに1回SQLを発行することになるので、
パフォーマンス的に課題が発生する恐れはあります。

ちなみに上記クエリの結果を、
DataTableに格納しているのでしたら、DataTable.Rows.Countプロパティにてレコード件数を取得できますので、
その件数があるかないかで出力を行うか否かの判断を行うと良いと思います。
(DataTableでなくDataReaderを利用している場合は別途COUNTを取らなければいけないかも・・・)

このパターンでのコーディングイメージは以下の感じです。

C#

1List<string> inClauseCondition = new List<string>(); 2inClauseCondition.Add("32,02,13"); 3inClauseCondition.Add("33,03,10"); 4inClauseCondition.Add("35,05,15"); 5 6StringBuilder sql = new StringBuilder(); 7sql.AppendLine(" SELECT"); 8sql.AppendLine(" T.*"); 9sql.AppendLine(" FROM"); 10sql.AppendLine(" ("); 11sql.AppendLine(" SELECT"); 12sql.AppendLine(" A.NAME AS NAME "); 13sql.AppendLine(" , A.ALERT AS ALERT"); 14sql.AppendLine(" , A.HOGE AS HOGE "); 15sql.AppendLine(" FROM"); 16sql.AppendLine(" TABLE_A A"); 17sql.AppendLine(" UNION ALL"); 18sql.AppendLine(" SELECT"); 19sql.AppendLine(" B.NAME"); 20sql.AppendLine(" , B.ALERT"); 21sql.AppendLine(" , B.HOGE"); 22sql.AppendLine(" FROM"); 23sql.AppendLine(" TABLE_B B"); 24sql.AppendLine(" ) T"); 25sql.AppendLine(" WHERE"); 26sql.AppendLine(" T.ALERT IN (:COND)"); 27 28string baseQuery = sql.ToString(); 29foreach (string cond in inClauseCondition) { 30 // 動的SQLを作成(IN句内部のみ差し替えている) 31 string query = baseQuery.Replace(":COND", cond); 32 33 // クエリの実行(中略) 34 35 // 取得レコードがあればファイル出力(DataTableを利用の場合) 36 if (dt.Rows.Count > 0) { 37 // ファイル出力処理(以下略) 38 } 39}

DB通信は最低限にし、C#側の制御に気合を入れる作戦

DB通信自体は1回に抑え込み、
後はC#側の制御にお任せというパターンです。
(ファイル出力時の制御が若干ややこしくなるかも・・・)

SQLとしては下記のイメージです。

SQL

1SELECT 2 CASE 3 WHEN T.ALERT IN (32,02,13) THEN '1' 4 WHEN T.ALERT IN (33,03,10) THEN '2' 5 WHEN T.ALERT IN (35,05,15) THEN '3' 6 ELSE NULL 7 END AS OUTPUT_NO 8, T.* 9FROM 10 ( 11 SELECT 12 A.NAME AS NAME 13 , A.ALERT AS ALERT -- 種別番号 14 , A.HOGE AS HOGE 15 FROM 16 TABLE_A A 17 UNION ALL -- ※取得レコードに重複が発生する場合は「UNION」の方が良いか? 18 SELECT 19 B.NAME 20 , B.ALERT -- 種別番号 21 , B.HOGE 22 FROM 23 TABLE_B B 24 ) T 25ORDER BY 26 OUTPUT_NO

上記のクエリで対象データを1回でごそっと抜き取って、
後はc#側の制御にお任せというのがこのアプローチとなります。

上記クエリでは擬似的に作成したOUTPUT_NOにて、
条件グループごとに採番を行っているため、
どのデータがどの条件グループに属するかの判別が可能です。

全部記載するのはしんどいのでc#で処理イメージのみ以下に記載します。
※あくまでイメージレベルなので動作確認していませんです

C#

1string query = "上記に記載しているクエリ"; 2 3// クエリの実行(中略) 4 5// 出力番号を格納した配列 6string[] outputNoArray = new string[] { "1", "2", "3"}; 7foreach (string no in outputNoArray) { 8 // LINQを使えばこんな感じでOUTPUT_NOごとのリストを取得できたはず(※DataTableの場合) 9 var outputData = dt.AsEnumerable() 10 .Where(r => r["OUTPUT_NO"] as string == no) 11 .ToList(); 12 13 if (outputData.Count > 0) { 14 // 上記のOUTPUT_NOごとにファイル出力を実施 15 } 16}

投稿2016/08/29 12:33

編集2016/08/29 14:01
Panzer_vor

総合スコア1636

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

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

0

どのようにDB接続しているかわかりませんが、

cn.ConnectionString = "Data Source=.;Initial Catalog=Northwind;Integrated Security=True";
cn.Open();

SqlCommand cmd = new SqlCommand("SELECT COUNT(*) FROM alertatble WHERE alert = 32 AND alert = 02 AND alert = 13", cn);

int Count = (int)cmd.ExecuteScalar();

のような形でカウント数をintにしてやればよいのではないでしょうか。

(集計した数が無しなら"0"、1つでもあるなら"2")とする意味はわかりませんが、
if(count > 0){
//1つでもあるときの処理
}else{
//データなしのときの処理
}

でよいような気もします。

投稿2016/08/26 02:08

s.t.

総合スコア2021

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

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

pro-poke5

2016/08/26 02:37 編集

ありがとうございます。 データベースへのアクセスは DBAccess dba = new DBAccess(); です 集計した値が~というのは、カラムの中で32、12、13の値が1つでもある場合とない場合が判別できれば良いということです、わかりづらくてすみません また、同じテーブル、カラムからですが、1行目の32,02,13の場合、2行目の33,03,10・・・・・・と1つのグループのように、別々にカラムに該当する数字があるか判断したいですが可能でしょうか?
s.t.

2016/08/26 02:54

WHERE句の中をOR条件にすれば問題ないかと思われます。 複数の条件毎にカウントするのであれば https://www.softel.co.jp/blogs/tech/archives/3267 こちらを参考にしてみてはいかがでしょうか。 戻り値をvarで受け取っておいて、デバッグなどで戻り値の型を見ると取り出し方もイメージしやすいと思います。
s.t.

2016/08/26 02:55

>1つでもある場合とない場合が判別できれば については前述のcount > 0で判定できると思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問