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

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

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

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

SQL Server

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

JOIN

これはSQL文のJOINに関するタグです。リレーショナルデータベースシステムの二つ以上のテーブルを結合する際に、この構文が利用されます。

SQL

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

Q&A

解決済

1回答

2344閲覧

ある条件でJOINできない場合、別の条件でJOINしたい

woria

総合スコア36

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

SQL Server

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

JOIN

これはSQL文のJOINに関するタグです。リレーショナルデータベースシステムの二つ以上のテーブルを結合する際に、この構文が利用されます。

SQL

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

0グッド

0クリップ

投稿2020/06/05 04:48

編集2020/06/05 05:11

実現したいこと

データの都合上、2つのテーブルをLEFT JOINした際にNULLになる場合、別の条件で計算した値を挿入したい

前提

以下の2つのテーブルが存在します。

GasAmount
|日付|県|単価|
|:--:|--:|
|2020/4/1|A|120|
|2020/4/1|B|122|
|2020/4/1|C|124|
|2020/5/1|A|121|
|2020/5/1|B|123|
|2020/5/1|C|125|
|2020/6/1|A|122|
|2020/6/1|B|124|
|2020/6/1|C|126|

GasAmountは月別のガソリン単価を示します。

Distance

|従業員|日付|県|距離|
|:--:|:--:|:--:|
|a|2020/4/1|A|1|
|b|2020/4/1|B|2|
|c|2020/4/1|E|3|
|a|2020/5/1|B|4|
|b|2020/5/1|A|5|
|c|2020/5/1|E|6|
|a|2020/6/1|A|7|
|b|2020/6/1|B|8|
|c|2020/6/1|C|9|

Distanceは各従業員が毎月どの県で何km走っているかを示します。

これらを組み合わせ、各従業員がいつ、どれだけ運賃=単価*距離を貰えるか計算します。

発生している問題・エラーメッセージ

SQL

1SELECT [Distance].*, [GasAmount].[単価] 2FROM [Distance] 3LEFT JOIN [GasAmount] ON 4[Distance].[] = [GasAmount].[] 5AND [Distance].[日付] = [GasAmount].[日付]

これにより、テーブルを組み合わせることができます。

|従業員|日付|県|距離|単価|
|:--:|:--:|:--:|:--:|
|a|2020/4/1|A|1|120|
|b|2020/4/1|B|2|122|
|c|2020/4/1|E|3||
|a|2020/5/1|B|4|123|
|b|2020/5/1|A|5|121|
|c|2020/5/1|E|6||
|a|2020/6/1|A|7|122|
|b|2020/6/1|B|8|124|
|c|2020/6/1|C|9|126|

しかし、データの都合上、[Distance].[県]には[GasAmount].[県]に存在しないデータが入ることがあり、その場合、その日付の県Aの単価を入れたいです。
その場合のSQLコードを教えてください。

補足情報(FW/ツールのバージョンなど)

SQL Server 2017

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

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

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

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

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

Orlofsky

2020/06/05 05:05

>SELECT [Distance].* [GasAmount].[単価] ↓ SELECT [Distance].[距離] * [GasAmount].[単価] では?
woria

2020/06/05 05:12

SQLを修正しました。
Orlofsky

2020/06/05 05:23

質問のテーブル定義はCREATE TABLEに、テーブル中のデータはINSERTに訂正できたほうがSQLを実行できるので的確なコメントが付き易いかと。
guest

回答1

0

ベストアンサー

予めと特定の県の部分も結合しておき、取得できない場合で差し替える

SQL

1SELECT [Distance].* 2 , COALESCE([GasAmount].[単価], GasAmount2.単価) as 単価 3FROM [Distance] LEFT JOIN [GasAmount] 4 ON [Distance].[] = [GasAmount].[] 5 AND [Distance].[日付] = [GasAmount].[日付] 6 LEFT JOIN [GasAmount] GasAmount2 7 ON [Distance].[日付] = [GasAmount2].[日付] 8 AND GasAmount2.='A'

以下はサブクエリー版。

SQL

1SELECT [Distance].* 2 , COALESCE([GasAmount].[単価] 3 , (select 単価 from GasAmount where 日付=Distance.日付 and='A') 4 ) as 単価 5FROM [Distance] LEFT JOIN [GasAmount] 6 ON [Distance].[] = [GasAmount].[] 7 AND [Distance].[日付] = [GasAmount].[日付]

どちらが性能が良いかは実行計画で確認して下さい。

投稿2020/06/05 05:30

sazi

総合スコア25195

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

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

woria

2020/06/05 05:37

COALESCEを初めて知りました。ありがとうございます!
sazi

2020/06/05 05:49 編集

条件によって取得先をスイッチするような場合、SQLでの考え方としては、From句で予めそれらの条件のデータを揃えてから、selectでcase式などで切り替えるように考えると良いですよ。
sousuke

2020/06/05 07:14

COALESCE内でサブクエリselectすると確か要素分だけselect回るんでオススメできません。isnullの方がselect1回で済むのでいいです。
sazi

2020/06/05 07:22 編集

>@sousukeさん 相関副問合せは当然駆動表のデータ数分問合せされるのが基本ですけど COALESCEとisNullでそのサブクエリーに関する実行計画が変わるって事ですか?
sazi

2020/06/05 07:37

case の式は真偽に関わらず、必ず評価されるってやつですね。 実行計画にまで反映されるかどうか分かりませんけど、確かにサブクエリーの場合はIsNullの方が良さそうですね。
sousuke

2020/06/05 10:58

『たとえば、COALESCE((subquery), 1) というコードを実行すると、サブクエリは 2 回評価されます。』 とあるので使うとしても第一案のように先に値を解決したり変数に一回受けてから使うように私はしています。isnullからcoalesceにする場合も往々にしてあるので、isnullするときでも結局のところ直でサブクエリは書きませんね…
sazi

2020/06/06 04:03

サブクエリーのパターンも回答したのは、母数が小さければサブクエリーであっても高速な場合があるから、取捨選択の為に回答しています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問