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

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

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

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

SQL

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

Q&A

解決済

3回答

840閲覧

SQLのLEFT JOINの条件の書き方

sasaki0628

総合スコア106

SQL Server

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

SQL

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

0グッド

1クリップ

投稿2023/06/16 03:15

以下のテーブルAとテーブルBからテーブルCを抽出したいのですが、JOIN の条件がわからず、うまく抽出することができないため教えていただきたいです。

【テーブルA】
NO, 売上日
1, 2023-04-16
2, 2023-05-16
3, 2023-06-16

【テーブルB】
適用日, 消費税
2023-04-01, 0.01
2023-04-15, 0.02
2023-05-01, 0.03
2023-05-15, 0.04
2023-06-01, 0.05
2023-06-15, 0.06

【求めたいテーブル(テーブルAとテーブルBをJOINした結果)】
NO, 売上日, 消費税
1, 2023-04-16, 0.02
2, 2023-05-16, 0.04
3, 2023-06-16, 0.06

【現在のSQL】
SELECT
テーブルA.NO
,テーブルA.売上日
,テーブルB.消費税
FROM テーブルA
LEFT JOIN テーブルB
ON テーブルB.適用日 <= テーブルA.売上日

【実行結果】
NO, 売上日, 消費税
1, 2023-04-16, 0.01
1, 2023-04-16, 0.02
2, 2023-05-16, 0.01
2, 2023-05-16, 0.02
2, 2023-05-16, 0.03
2, 2023-05-16, 0.04
3, 2023-06-16, 0.01
3, 2023-06-16, 0.02
3, 2023-06-16, 0.03
3, 2023-06-16, 0.04
3, 2023-06-16, 0.05
3, 2023-06-16, 0.06

テーブルB.適用日 <= テーブルA.売上日、の条件の中で最も新しい適用日の消費税のみをJOINしたいですが、書き方がわかりません。

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2023/06/16 03:33 編集

DB サーバーはタグの SQL Server なのですか? あなたの言うJOIN の意味は SQL 文で言う JOIN とは違うようですが、具体的にどういうことか説明できますか?
guest

回答3

0

LEAD関数を使って有効な日付の範囲を求めたものと結合します。

SQL

1select 2 ta.*, tb.消費税 3from tbl_a as ta 4 left join ( 5 select *, lead(適用日, 1, cast('9999/12/31' as date)) over(order by 適用日) as 次回適用日 6 ) as tb 7 on ta.売上日 >= tb.適用日 and ta,売上日 < tb,次回適用日

※手打ちで検証していません。悪しからず。

投稿2023/06/16 07:38

編集2023/06/16 07:39
sazi

総合スコア25430

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

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

sasaki0628

2023/06/19 00:32

lead関数は知りませんでした。シンプルでわかりやすいですね。ありがとうございます。
guest

0

もし消費税マスタの形をいじれるならば、適用開始日・終了日を持って left join 一発でやる方法もあります。

適用開始日, 適用終了日(NULLは終了日未定), 消費税
2023-04-01, 2023-04-14, 0.01
2023-04-15, 2023-04-30, 0.02
2023-05-01, NULL, 0.03

投稿2023/06/16 06:22

68user

総合スコア2048

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

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

sasaki0628

2023/06/16 07:05

なるほど、こちらが範囲指定ならば簡単に書けるんですね。(ただし今回は修正することができません…。)ありがとうございます。
guest

0

ベストアンサー

とりあえずmysqlで書いておきます、ご自身のSQLへの適用は調整ください

SQL

1create table tbl_a(no int primary key,d date); 2insert into tbl_a values 3(1,'2023-04-16'), 4(2,'2023-05-16'), 5(3,'2023-06-16'); 6 7create table tbl_b(d date,tax double); 8insert into tbl_b values 9('2023-04-01',0.01), 10('2023-04-15',0.02), 11('2023-05-01',0.03), 12('2023-05-15',0.04), 13('2023-06-01',0.05), 14('2023-06-15',0.06); 15 16select t1.no,t1.d,t2.tax from tbl_a as t1 17left join tbl_b as t2 18on t1.d>t2.d 19and not exists(select 1 from tbl_b where d<t1.d and d>t2.d)

投稿2023/06/16 03:38

yambejp

総合スコア117732

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

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

sasaki0628

2023/06/16 06:09

回答ありがとうございます。EXISTSは知りませんでした。 テーブルBが 適用日, 消費税 2023-04-01, 0.01 2023-04-15, 0.02 2023-04-16, 0.07 2023-05-01, 0.03 2023-05-15, 0.04 2023-06-01, 0.05 2023-06-15, 0.06 だったときに、売上日が 2023-04-16 のときに 適用日が 2023-04-15 のものが結合されてしまいます。(2023-04-16 が結合されたい。) 教えていただいたSQLを参考にして SELECT tbl_a.NO, tbl_a.売上日, tbl_b.消費税 FROM tbl_a LEFT JOIN tbl_b AS tbl_b_1 on tbl_a.売上日 >= tbl_b.適用日 AND NOT EXISTS(SELECT 1 FROM tbl_b AS tbl_b_2 WHERE tbl_b_2.適用日 < tbl_a.売上日 AND tbl_b_2.適用日 > tbl_b_1.適用日) としたところ、今度は 2023-04-16 と 2023-04-15 の二つが結合されました。 (tbl_a.売上日 >= tbl_b.適用日 としているため。) そこで、サブクエリで適用日が最大のものに絞った後に結合をしました。 SELECT tbl_a_1.NO, tbl_a_1.売上日, tbl_b_1.消費税 FROM tbl_a AS tbl_a_1 LEFT JOIN( SELECT tbl_a_2.売上日, tbl_b_2.消費税 FROM tbl_b AS tbl_b_2 LEFT JOIN( SELECT tbl_a_3.売上日, MAX(tbl_b_3.適用日) AS 適用日 FROM tbl_a AS tbl_a_3 LEFT JOIN tbl_b AS tbl_b_3 ON tbl_a_3.売上日 >= tbl_b_3.適用日 AND NOT EXISTS(SELECT 1 FROM tbl_b AS tbl_b_4 WHERE   tbl_b_4.適用日 < tbl_a_3.売上日 AND tbl_b_4.適用日 > tbl_b_3.適用日 ) GROUP BY tbl_a_3.売上日 ) AS tbl_a_2 ON tbl_b_2.適用日 = tbl_a_2.適用日 ) AS tbl_b_1 ON tbl_a_1.売上日 = tbl_b_1.売上日 サブクエリを3回も使い、良い書き方ではないように思います。もし他にシンプルな書き方があれば教えていただけないでしょうか。
yambejp

2023/06/16 06:17

同じ日がふくまれるならこう select t1.no,t1.d,t2.tax,t2.d from tbl_a as t1 left join tbl_b as t2 on t1.d>=t2.d and not exists(select 1 from tbl_b where d<=t1.d and d>t2.d)
sasaki0628

2023/06/16 06:57

ありがとうございます。 実は、WHERE句のところの意味がよくわかっていません。 売上日が 2023-04-16 のとき、 d <= t1.d においては、2023-04-16 以下の日付として 2023-04-01, 2023-04-15, 2023-04-16 の3つに絞られていると思いますが、 d>t2.d においては、何をしているのでしょうか? 2023-04-01, 2023-04-15, 2023-04-16 > 2023-04-01, 2023-04-15, 2023-04-16 のとき、2023-04-01, 2023-04-15 が残るのでしょうか?
sasaki0628

2023/06/16 10:46

EXISTS句を調べ学習し、理解しました。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.31%

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

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

質問する

関連した質問