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

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

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

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

SQL

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

Q&A

解決済

3回答

1347閲覧

SQL グループ化する時の条件に判断を追加したい

nuko3

総合スコア31

SQL Server

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

SQL

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

0グッド

0クリップ

投稿2021/07/15 05:24

SQLServerのビューを利用して集計用のビューを作成しています。
WHERE句で一部の条件を外した所までは行けたのですが、IF文のような判断を追加したいんですが、書き方がわかりません。(出来るのかすら分かりませんが…)

以下のようなテーブルから、[コード]でグループ化、条件で[削除]をFalseのみ、までは行けました。

|コード|製品名|受注数|再検品|枝番|削除|
|:--|:--:|--:|--:|
|123|エビ|300|0|1|False|
|456|カニ|300|0|1|False|
|789|ウニ|300|0|1|False|
|123|エビ|400|0|2|False|
|123|エビ|450|1|2|False|
|456|カニ|600|0|2|True|
|789|ウニ|700|0|2|False|

SQL

1SELECT MAX(コード) AS コード, MAX(製品名) AS 製品名, SUM(受注数) AS 受注数 2FROM 受注テーブル 3WHERE 削除 = 'False' 4GROUP BY コード
コード製品名受注数
123エビ1150
456カニ300
789ウニ1000

しかしこの文だと、再検品を追加すると前の分も加算されてしまうので、
グループ内の[コード]と[枝番]が同じで[再検品]に「0」と「1」があった場合、「0」の行は除き「1」の行を集計に入れるという事がしたいです。
何か良い方法はありますでしょうか?
理想形↓

コード製品名受注数
123エビ750
456カニ300
789ウニ1000

###環境
Windows Server 2012R2
SQL Server 2012

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

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

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

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

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

sazi

2021/07/15 12:13

同じ[コード]と[枝番]では[再検品]は1件だけですか?
guest

回答3

0

入れ子だとごちゃごちゃするので仮想テーブルを使って書きました。
どうでしょうか?

SQL

1-- まず集計対象となるデータの仮想テーブルを作る 2WITH target AS ( 3 SELECT 4   コード 5  , 枝番 6 , MAX(再検品) AS MAX再検品 7 FROM 受注テーブル 8 WHERE 削除 = 'False' 9 GROUP BY 10  コード 11 ,枝番 12) 13 14-- 仮想テーブルと受注テーブルをJOINしたものをGROUP化してSUMする 15SELECT 16 J.コード 17 ,J.製品名 18 ,SUM(J.受注数) 19FROM 受注テーブル AS J INNER JOIN target AS T 20 ON J.コード = T.コード 21AND J.枝番 = T.枝番 22AND J.再検品 = T.MAX再検品 23GROUP BY 24 J.コード 25 ,J.製品名 26 27

投稿2021/07/15 14:58

odataiki

総合スコア973

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

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

0

ベストアンサー

コードと枝番が同じ場合は、再検品の値がより大きい行を集計に入れたいということであっていますか?

あっているのであれば、以下のようなクエリになるかと思います。

SQL

1SELECT MAX(コード) AS コード, MAX(製品名) AS 製品名, SUM(受注数) AS 受注数 2FROM 受注テーブル G1 3WHERE 削除 = 'False' 4AND NOT EXISTS ( 5 SELECT * 6 FROM 受注テーブル G2 7 WHERE G2.削除 = 'False' 8 AND G1.コード = G2.コード 9 AND G1.枝番 = G2.枝番 10 AND G1.再検品 < G2.再検品 11) 12GROUP BY コード

あるいはWindow関数を使う方法もあります、

SQL

1SELECT MAX(コード) AS コード, MAX(製品名) AS 製品名, SUM(受注数) AS 受注数 2FROM ( 3 SELECT *, ROW_NUMBER() OVER(PARTITION BY コード, 枝番 ORDER BY 再検品 DESC) AS ランク 4 FROM 受注テーブル 5 WHERE 削除 = 'False' 6) T 7WHERE ランク = 1 8GROUP BY コード

投稿2021/07/15 14:37

neko_the_shadow

総合スコア2349

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

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

nuko3

2021/07/15 23:34

ありがとうございます!理想的な形になれました!
guest

0

グループ内の[コード]と[枝番]が同じで[再検品]に「0」と「1」があった場合、「0」の行は除き「1」の行を集計に入れるという事がしたいです。

やり方は色々あるだろうけども、直感的なわかりやすさなら

  1. 「再検品=1」の行だけ抽出
  2. 1.の表と元の票を「コード」「枝番」「再検品=0」でJOIN
  3. CASE (Transact-SQL)文で1.の表がNULLでない場合は1.の表から、それ以外は元の表から集計用のデータを抽出する
  4. 3.できた表を質問文の条件で集計

投稿2021/07/15 06:12

gentaro

総合スコア8947

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

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

nuko3

2021/07/15 07:02

回答ありがとうございます。 実際にやってみて1.と2.までは行けて再検品がある0のものを抽出できる所までは出来ました。 3.の原理はなんとなく理解出来るのですが、どう書けばいいのかわかりません…
gentaro

2021/07/15 07:35

書き方はリファレンスに載ってますし、ググればいくらでも事例が見つかるでしょう。 「わかりません」と言って解決するものじゃありません。 わからないなら何をどこまで調べてどの部分が読み解けなかったのか説明しましょう。
nuko3

2021/07/15 23:33

すみません、文章を端折りすぎました。 条件の書き方が分からず、SELECT CASE ID IS NULL ...と書いてもエラー(','付近に不適切な構文があります)と出るので、根本的な事か3.の文章の読み解き方が間違っているんだろうなと思ってリファレンス見たり色々調べながらやっていましたがうまく行かず悩んでいました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問