前提・実現したいこと
エクセルでいうCOUNTIFのMAX版のようなものがSQLにないでしょうか?
:SQLserver
質問
よくあるヘッダと明細のテーブルにて
ヘッダ
伝票番号 0001
明細 日付 金額
明細番号001 2011/11/01 1900
明細番号002 2011/11/02 2900
明細番号003 2011/11/03 3900
明細番号004 2011/11/04 4900
明細番号005 2999/12/31 5900
があるとして、明細データのサマリーを持たせた伝票ヘッダの情報を取得する際、
2999/12/31を覗いた値の中の最大値2011/11/04を「カラムA」として取得したいです。
取得データとしては2999/12/31も含めた金額のサマリーや、2999/12/31も含めた明細数のカウントも必要となります。
この場合一番スマートなSQLはどのようになるでしょうか。
ぱっと思いついたのは
サブクエリで明細の別テーブル(2999/12/31を除いたもの)を用意し、それをJOINしてMAXを取る方法なのですが、エクセルで言うCOUNTIFのMAX版みたいなのがあれば、別テーブルいらないのかなと思いました。
もう少しいい方法はありますか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
ベストアンサー
こういうことでしょうか?
sql
1WITH TestTable AS ( 2 SELECT N'伝票番号001'AS [Denpyo], N'明細番号001' AS [Meisai], '2011/11/01' AS [Date], 1900 AS [Price] UNION ALL 3 SELECT N'伝票番号001'AS [Denpyo], N'明細番号002' AS [Meisai], '2011/11/02' AS [Date], 2900 AS [Price] UNION ALL 4 SELECT N'伝票番号001'AS [Denpyo], N'明細番号003' AS [Meisai], '2011/11/03' AS [Date], 3900 AS [Price] UNION ALL 5 SELECT N'伝票番号001'AS [Denpyo], N'明細番号004' AS [Meisai], '2011/11/04' AS [Date], 4900 AS [Price] UNION ALL 6 SELECT N'伝票番号001'AS [Denpyo], N'明細番号005' AS [Meisai], '2999/12/31' AS [Date], 5900 AS [Price] UNION ALL 7 8 SELECT N'伝票番号002'AS [Denpyo], N'明細番号201' AS [Meisai], '2020/11/11' AS [Date], 1900 AS [Price] UNION ALL 9 SELECT N'伝票番号002'AS [Denpyo], N'明細番号202' AS [Meisai], '2020/12/12' AS [Date], 2900 AS [Price] UNION ALL 10 SELECT N'伝票番号002'AS [Denpyo], N'明細番号205' AS [Meisai], '2999/12/31' AS [Date], 5900 AS [Price] 11) 12 13SELECT * 14 15-- MAXの中に CASE 文を書く。 16-- 特定の日付だったらNULLに差し替えてMAXの候補に入らないようにしてしまう 17, MAX( 18 CASE WHEN [Date] = '2999/12/31' THEN NULL 19 ELSE [Date] 20 END 21 ) OVER(PARTITION BY Denpyo) 22 23 AS [MAX内でCASE] 24 25-- サブクエリで取る。 26, ( 27 SELECT MAX([Date]) FROM TestTable sub 28 WHERE [Date] <> '2999/12/31' 29 AND sub.Denpyo = t.Denpyo 30 GROUP BY sub.Denpyo 31 ) 32 AS [サブクエリ] 33 34FROM TestTable t 35ORDER BY t.Denpyo, t.Meisai
とりあえず 2 案。
でもサブクエリの方が個人的にしっくりくるかな…? どうでしょう
投稿2018/11/21 05:05
総合スコア1126
0
一回で済ませなくてもいいような気もしますが
SQL
1WITH W AS( 2 SELECT * FROM 明細データ WHERE 伝票番号 = '0001' 3) 4SELECT COUNT(T.明細) COUNT, SUM(T.金額) SUM, ( 5 SELECT MAX(T2.日付) FROM W T2 WHERE T2.日付 <> '2999-12-31' 6) カラムA 7FROM W T
投稿2018/11/21 04:54
総合スコア13749
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/11/21 05:17
2018/11/21 05:24
0
こんな感じですかね
SQL
1create table tbl(明細 varchar(10),日付 date,金額 int); 2insert into tbl values 3('001','2011/11/01','1900'), 4('002','2011/11/02','2900'), 5('003','2011/11/03','3900'), 6('004','2011/11/04','4900'), 7('005','2999/12/31','5900'); 8select * from tbl as t1 where not exists( 9select 1 from tbl where and 日付<'2999/12/31' and t1.金額<金額 10) and 日付<'2999/12/31'
修正
SQL
1create table tbl(伝票番号 varchar(10),明細 varchar(10),日付 date,金額 int); 2insert into tbl values 3('0001','001','2011/11/01','1900'), 4('0001','002','2011/11/02','2900'), 5('0001','003','2011/11/03','5000'), 6('0001','004','2011/11/04','4900'), 7('0001','005','2999/12/31','5900'), 8('0002','001','2011/11/05','5000');
2999/12/31を除く最大値の日付を持つ金額
SQL
1select 伝票番号,金額 from tbl as t1 where not exists( 2select 1 from tbl where 日付<'2999/12/31' and t1.日付<日付 and t1.伝票番号=伝票番号 3) and 日付<'2999/12/31' and 伝票番号='0001'
投稿2018/11/21 04:46
編集2018/11/21 05:15総合スコア114839
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/11/21 04:59
2018/11/21 05:00
2018/11/21 05:24 編集
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/11/21 05:08
2018/11/21 05:18
2018/11/21 05:22