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

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

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

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

Q&A

解決済

2回答

467閲覧

複数行でmaxしたい

a-nakanishi

総合スコア1

SQL Server

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

0グッド

0クリップ

投稿2022/07/09 07:43

編集2022/07/09 20:03

よろしくお願いいたします。
Microsoft SQL Serverを使用しています。

適用終了日が最新(6/30)の中で、適用開始日が最新(3/1)のものを取ってきたいです。
朝からずっと考えているのですが、適用開始日4/1で適用終了日が6/30のものしか取ってこれません。
どなたかご教示お願い致します。

●表

ID適用開始日適用終了日単価
14/15/31100
13/16/30200
12/16/30250

●抽出後

ID適用開始日適用終了日単価
13/16/30200
CREATE TABLE [dbo].[マスタ外注単価]( [加工先コード] [varchar](10) NULL, [商品コード] [varchar](25) NULL, [数量未満] [decimal](13, 0) NULL, [適用開始日] [datetime] NULL, [適用終了日] [datetime] NULL, [仕入本体単価] [decimal](13, 0) NULL, ) コード
select * from( select distinct 2 区分,n4.加工先コード,n4.商品コード,適用開始日,適用終了日,開始日,終了日,数量未満,仕入本体単価            from [dbo].[マスタ外注単価]n4 inner join( select 加工先コード,商品コード,max(適用終了日)as 終了日 from[dbo].[マスタ外注単価] where 適用終了日>='2021/12/01' and 適用終了日 is not null group by 加工先コード,商品コード )n5 on n4.商品コード=n5.商品コード and n4.加工先コード=n5.加工先コード inner join( select 加工先コード,商品コード,max(適用開始日)as 開始日 from[dbo].[マスタ外注単価] where 適用終了日>='2021/12/01' and 適用終了日 is not null group by 加工先コード,商品コード )n6 on n4.商品コード=n6.商品コード and n4.加工先コード=n6.加工先コード where n4.商品コード='100000054' and 適用終了日=終了日)b where 適用開始日 = max(適用開始日) コード

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2022/07/09 07:59

どこまでできているのか、質問者さんの考えた SQL 文を質問欄に追記できませんか? SSMS を使ってテーブル生成のための CREATE 文を出力してそれを質問欄に追記できませんか?
a-nakanishi

2022/07/09 08:15

回答まことにありがとうございます。追記しました。 不足ありましたら教えてください。 どうぞよろしくお願い致します。
guest

回答2

0

ベストアンサー

「IDごとに適用終了日が最新のデータを取得したい、適用終了日が最新のものが複数ある場合は、適用開始日がより新しいデータが欲しい」

やりたいことはこれであっていますか?

であれば、以下のようなSQLで実現できるかと思います。

SQL

1SELECT * 2FROM ( 3 SELECT *, RANK() OVER(PARTITION BY id ORDER BY 適用終了日 DESC, 適用開始日 DESC) AS rnk 4 FROM5) T 6WHERE rnk = 1

投稿2022/07/09 09:03

neko_the_shadow

総合スコア2225

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

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

a-nakanishi

2022/07/09 11:03

ご回答ありがとうございます。 日本語が分かりづらく申し訳ありません、おっしゃる通りです。 overは使ったことがありませんでした。どのようなことに使えるのか改めて勉強します。 こんなに短い文でできるのですね。 どうもありがとうございました!
guest

0

これでひとまず適応終了日が最新のレコードを取得して

select ...略... where 適応終了日 = max(適応終了日)

その中から適応開始日が最新のレコードを取得します

select * from (select ...略... where 適応終了日 = max(適応終了日)) where 適応開始日 = max(適応開始日)

投稿2022/07/09 08:30

MikenekoSamane

総合スコア102

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

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

a-nakanishi

2022/07/09 09:05

ご回答ありがとうございます。 コードを編集しました。 適用終了日が最新のレコードを取得することはできました。 ただwhere 適応開始日 = max(適応開始日)にすると 集計が HAVING 句または選択リスト内のサブクエリにある場合、および集計する列が外部参照の場合にだけ、WHERE 句に集計を含めることができます。 というエラーが出ます。 申し訳ありません、どこを直せばエラーが出なくなるのでしょうか?
MikenekoSamane

2022/07/09 09:21

失礼しました構文ミスってました 集計関数を使った条件をhaving句に置けば大丈夫です あとサブクエリに名前が必要かもしれません。as ~ で名前を付けてあげてください。 ``` select * from (select ...略... having 適応終了日 = max(適応終了日)) as tmp having 適応開始日 = max(適応開始日) ```
a-nakanishi

2022/07/09 10:33

何度も申し訳ございません。 サブクエリに名前を付けて、havingにすると、 列 'b.適用開始日' は HAVING 句内では無効です。この列は集計関数または GROUP BY 句に含まれていません。 とエラーが出ます。 2番目にjoinしているが効いていないので、位置がおかしいのかなと思いました。。 でもどこにGROUP BYしていいのか分からずです。 neko_the_shadow様の案でできたのですが、もしサブクエリでも同じことができればと思ったのですが。
MikenekoSamane

2022/07/09 10:48

group by にhavingで使う列を入れたらできますかね。 知識不足で確実な解決策はわかりませんすみません 多重selectよりももうひと方の方がスマートな気もします。
a-nakanishi

2022/07/09 11:00

とんでもございません。 group byやhavingなど色んな場所で試してみたのですができませんでした。 色々とどうもありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問