C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[13]: SQLの結合について


(過去ログ 170 を表示中)

[トピック内 14 記事 (1 - 14 表示)]  << 0 >>

■98123 / inTopicNo.1)  SQLの結合について
  
□投稿者/ 鏡月 (65回)-(2021/09/22(Wed) 11:18:08)

分類:[データベース全般] 

いつもお世話になっております。
ご存知の方がおりましたらご教授願います。

同一品番の過去の作業内容と現在の作業内容を出力するSQL文を作成しております。
過去の作業内容:TBL_実績
フィールド:品番、作業ID、作業内容
データ:1111、0001、洗浄
   1111、0002、乾燥
   1111、0003、梱包

現在の作業内容:TBL_マスタ
フィールド:品番、作業ID、作業内容
データ:1111、0001、洗浄
   1111、0003、梱包
   1111、0004、発送

各テーブルに上記データが登録されていると仮定し出力したいデータは下記を想定しております。
フィールド:品番、過去作業ID、過去作業内容、現在作業ID、現在作業内容
データ: 1111、0001、洗浄、0001、洗浄
    1111、0002、乾燥、NULL、NULL
    1111、0003、梱包、0003、梱包
    1111、NULL、NULL、0004、発送

下記のようなSQLを作成してみたのですが上記の出力したいデータの用に出力されませんでした。
上記のようなデータを出力するにはどのように作成すればよろしいのでしょうか。
SELECT
TBL_実績.品番
,TBL_実績.作業ID AS 過去作業ID
,TBL_実績.作業内容 AS 過去作業内容
,TBL_マスタ.作業ID AS 現在作業ID
,TBL_マスタ.作業内容 AS 現在作業内容
FROM TBL_実績
FULL JOIN TBL_マスタ ON TBL_マスタ.品番 = TBL_実績.品番 AND TBL_実績.作業ID = TBL_マスタ.作業ID






引用返信 編集キー/
■98124 / inTopicNo.2)  Re[1]: SQLの結合について
□投稿者/ 魔界の仮面弁士 (3179回)-(2021/09/22(Wed) 11:46:00)
掲示板投稿時の注意事項に
『半角カナは使用しないでください。文字化けの原因になります。』
という一文があったかと思います。次回以降ご留意ください。

No98123 (鏡月 さん) に返信
> 上記のようなデータを出力するにはどのように作成すればよろしいのでしょうか。
> SELECT
> TBL_実績.品番
どのデータベースを使っているか分からないのですが、
たとえば Oracle であれば
 COALESCE(TBL_実績.品番, TBL_マスタ.品番) AS 品番
かな。
引用返信 編集キー/
■98125 / inTopicNo.3)  Re[2]: SQLの結合について
□投稿者/ 鏡月 (66回)-(2021/09/22(Wed) 13:04:18)
2021/09/22(Wed) 13:08:26 編集(投稿者)
2021/09/22(Wed) 13:08:20 編集(投稿者)

No98124 (魔界の仮面弁士 さん) に返信

魔界の仮面弁士様ご返信ありがとうございます。

> 掲示板投稿時の注意事項に
> 『半角カナは使用しないでください。文字化けの原因になります。』
> という一文があったかと思います。次回以降ご留意ください。
⇒大変失礼いたしました。次回以降気を付けます。

> ■No98123 (鏡月 さん) に返信
>>上記のようなデータを出力するにはどのように作成すればよろしいのでしょうか。
>>SELECT
>> TBL_実績.品番
> どのデータベースを使っているか分からないのですが、
> たとえば Oracle であれば
>  COALESCE(TBL_実績.品番, TBL_マスタ.品番) AS 品番
> かな。
⇒データベースの参照方法がいまいちわからなくて申し訳ございませんがManagement Studioには「SQL Server 13.0...」と記載されております。
私の理解不足でしたら申し訳ございませんが「COALESCE」ですと値の置き換えだと思いますので出力したいデータのようにはうまく動作しませんでした。

引用返信 編集キー/
■98126 / inTopicNo.4)  Re[3]: SQLの結合について
□投稿者/ 魔界の仮面弁士 (3180回)-(2021/09/22(Wed) 13:24:02)
No98125 (鏡月 さん) に返信
> Management Studioには「SQL Server 13.0...」と記載されております。
13.0 系統ということは、SQL Server 2016 ですね。

> 私の理解不足でしたら申し訳ございませんが「COALESCE」ですと値の置き換えだと思いますので出力したいデータのようにはうまく動作しませんでした。
SQL Server でも COALESCE は使えます。

また、COALESCE 無しで同じことをする場合は下記のように書けますが、
3 テーブル以上になる場合は、COALESCE を使った方が手っ取り早いでしょう。


<案1> ISNULL 関数

SELECT 品番 = ISNULL(TBL_マスタ.品番, TBL_実績.品番)
, TBL_実績.作業ID AS 過去作業ID
, TBL_実績.作業内容 AS 過去作業内容
, -- 以下略


<案2> CASE 式

SELECT 品番 = CASE
WHEN TBL_マスタ.品番 IS NULL THEN TBL_実績.品番
WHEN TBL_実績.品番 IS NULL THEN TBL_マスタ.品番
END
, TBL_実績.作業ID AS 過去作業ID
, TBL_実績.作業内容 AS 過去作業内容
, -- 以下略
引用返信 編集キー/
■98127 / inTopicNo.5)  Re[4]: SQLの結合について
□投稿者/ 鏡月 (67回)-(2021/09/22(Wed) 13:32:16)
2021/09/22(Wed) 13:44:06 編集(投稿者)

魔界の仮面弁士様

ご返信ありがとうございます。
記載方法が分かり辛くなって申し訳ございません。

こちらの本番環境で記載したSQLを実行した場合、FULL JOINの結果ではなくLEFT JOINのような結果が出力されております。
出力データ
1111、0001、洗浄、0001、洗浄
1111、0002、乾燥、NULL、NULL
1111、0003、梱包、0003、梱包

下記のデータが出力されなかったため、当初はSQL文の記載方法に間違いがあるのではないかと考えておりました。
1111、NULL、NULL、0004、発送

SQL Fiddleのサイトにてサンプルデータを作成し、FULL JOINのSQLを実行した時にある程度想定されたデータが出力されました。
こちらを踏まえると本番環境ではFULL JOINは使用不可とのことになるのでしょうか。

尚、本番環境では
「AND TBL_実績.作業ID = TBL_マスタ.作業ID」の記載を無くすとCROSS JOIN のような結果が出力されます。

引用返信 編集キー/
■98129 / inTopicNo.6)  Re[5]: SQLの結合について
□投稿者/ 魔界の仮面弁士 (3182回)-(2021/09/22(Wed) 14:07:38)
No98127 (鏡月 さん) に返信
> こちらの本番環境で記載したSQLを実行した場合、FULL JOINの結果ではなくLEFT JOINのような結果が出力されております。
当方では問題なく出力されているように見えます。
https://www.vb-user.net/junk/replySamples/2021.09.21.13.57/FullJoin.png

掲示板に投稿し忘れている追加条件がありませんか?

実は WHERE 句や副問い合わせが追加されていたとか、あるいは
品番列の末尾に空白文字が含まれていて JOIN 条件がマッチしていなかったとか。
引用返信 編集キー/
■98130 / inTopicNo.7)  Re[6]: SQLの結合について
□投稿者/ 鏡月 (68回)-(2021/09/22(Wed) 14:10:15)
2021/09/22(Wed) 14:37:53 編集(投稿者)

No98129 (魔界の仮面弁士 さん) に返信
> ■No98127 (鏡月 さん) に返信
>>こちらの本番環境で記載したSQLを実行した場合、FULL JOINの結果ではなくLEFT JOINのような結果が出力されております。
> 当方では問題なく出力されているように見えます。
> https://www.vb-user.net/junk/replySamples/2021.09.21.13.57/FullJoin.png
>
> 掲示板に投稿し忘れている追加条件がありませんか?
>
> 実は WHERE 句や副問い合わせが追加されていたとか、あるいは
> 品番列の末尾に空白文字が含まれていて JOIN 条件がマッチしていなかったとか。
⇒魔界の仮面弁士様
 ご返信ありがとうございます。

 間違っている箇所がなんとなくわかったのですがうまく説明することが出来ません。
 詳細情報共有の為、魔界の仮面弁士様が行っているようにキャプチャーデータを載せたいのですがどのようにやればよろしいのでしょうか。
引用返信 編集キー/
■98131 / inTopicNo.8)  Re[7]: SQLの結合について
□投稿者/ 魔界の仮面弁士 (3183回)-(2021/09/22(Wed) 14:52:47)
No98130 (鏡月 さん) に返信
>  間違っている箇所がなんとなくわかったのですがうまく説明することが出来ません。
「現象を再現可能な最低限の情報」として
・CREATE TABLE
・INSERT INTO
・SELECT
の 3 つを掲載すれば良いのでは無いですか?


>  詳細情報共有の為、魔界の仮面弁士様が行っているようにキャプチャーデータを載せたいのですがどのようにやればよろしいのでしょうか。
現在実行している SQL をそのまま記載すれば良い気がしますが、
画像情報で無いと説明し辛いということでしょうか。

とりあえず、OneDrive に保存して、その公開 URL を貼ってみるとか。
https://support.microsoft.com/ja-jp/office/9fcc2f7d-de0c-4cec-93b0-a82024800c07
引用返信 編集キー/
■98132 / inTopicNo.9)  Re[8]: SQLの結合について
□投稿者/ 鏡月 (69回)-(2021/09/22(Wed) 15:06:55)
2021/09/22(Wed) 15:24:24 編集(投稿者)

No98131 (魔界の仮面弁士 さん) に返信
> ■No98130 (鏡月 さん) に返信
>> 間違っている箇所がなんとなくわかったのですがうまく説明することが出来ません。
> 「現象を再現可能な最低限の情報」として
> ・CREATE TABLE
> ・INSERT INTO
> ・SELECT
> の 3 つを掲載すれば良いのでは無いですか?
>
>
>> 詳細情報共有の為、魔界の仮面弁士様が行っているようにキャプチャーデータを載せたいのですがどのようにやればよろしいのでしょうか。
> 現在実行している SQL をそのまま記載すれば良い気がしますが、
> 画像情報で無いと説明し辛いということでしょうか。
>
> とりあえず、OneDrive に保存して、その公開 URL を貼ってみるとか。
> https://support.microsoft.com/ja-jp/office/9fcc2f7d-de0c-4cec-93b0-a82024800c07
⇒ご返信ありがとうございます。
 失礼になるかとは思いますがデータベース言語を記載させていただきます。

WHERE句内に指図IDを任意で入力し実績データの作業情報の比較データを出力したいと考えておりますがマスタ内に指図ID情報が存在しない為、出力データに差異が発生しておりました。
任意の指図IDの実績データ及びマスタデータを出力するSQLはどのようになるのでしょうか。
※下記載しておりますSQLは先ほどまで実行していたSQLになります。


CREATE TABLE 実績 ([指図ID] varchar(4),[品番] varchar(4), [作業ID] varchar(4), [作業内容] nvarchar(10));
CREATE TABLE マスタ ([品番] varchar(4), [作業ID] varchar(4), [作業内容] nvarchar(10));

INSERT INTO 実績 VALUES
('A','1111', '0001', N'洗浄'),
('A','1111', '0002', N'乾燥'),
('A','1111', '0003', N'梱包'),
('A','3333', '0001', N'洗浄'),
('A','3333', '0002', N'乾燥'),
('A','3333', '0003', N'梱包'),
('B','1111', '0001', N'洗浄'),
('B','1111', '0002', N'乾燥'),
('B','1111', '0003', N'梱包'),
('B','2222', '0001', N'洗浄'),
('B','2222', '0002', N'乾燥'),
('B','2222', '0003', N'梱包')
;

INSERT INTO マスタ VALUES
('1111', '0001', N'洗浄'),
('1111', '0003', N'梱包'),
('1111', '0004', N'出荷'),
('2222', '0001', N'洗浄'),
('2222', '0003', N'梱包'),
('2222', '0004', N'出荷'),
('3333', '0002', N'乾燥'),
('3333', '0005', N'検証')
;

SELECT
指図ID
,COALESCE(実績.品番,マスタ.品番) AS 品番
,実績.作業ID AS 過去作業ID
,実績.作業内容 AS 過去作業内容
,マスタ.作業ID AS 現在作業ID
,マスタ.作業内容 AS 現在作業内容
FROM 実績
FULL JOIN マスタ ON マスタ.品番 = 実績.品番 AND 実績.作業ID = マスタ.作業ID
WHERE 実績.指図ID = 'A'
引用返信 編集キー/
■98133 / inTopicNo.10)  Re[9]: SQLの結合について
□投稿者/ 魔界の仮面弁士 (3184回)-(2021/09/22(Wed) 16:15:50)
No98132 (鏡月 さん) に返信
> WHERE 実績.指図ID = 'A'

やはり条件が漏れていましたか。
こうなると、当初の質問とは似て非なる問題になってしまいますよね。


さて結局のところ、そのデータに対してどういう結果を求めているのでしょうか?
条件もデータも変わってしまったので、当初の質問内容からでは「やりたいこと」を判断できません。


ひとまず WHERE 句が無ければ、FULL OUTER JOIN によって
下記の 15 行のデータになります。

そこに WHERE 実績.指図ID = 'A' を加えれば、
1〜6 行目だけに絞り込まれるのは必然かと。

行|指図ID|品番|過去作業ID|過去作業内容|現在作業ID|現在作業内容
--+------+----+----------+------------+----------+------------
 1|A     |1111| 0001     |洗浄        |0001      |洗浄
 2|A     |1111| 0002     |乾燥        |NULL      |NULL
 3|A     |1111| 0003     |梱包        |0003      |梱包
 4|A     |3333| 0001     |洗浄        |NULL      |NULL
 5|A     |3333| 0002     |乾燥        |0002      |乾燥
 6|A     |3333| 0003     |梱包        |NULL      |NULL
 7|B     |1111| 0001     |洗浄        |0001      |洗浄
 8|B     |1111| 0002     |乾燥        |NULL      |NULL
 9|B     |1111| 0003     |梱包        |0003      |梱包
10|B     |2222| 0001     |洗浄        |0001      |洗浄
11|B     |2222| 0002     |乾燥        |NULL      |NULL
12|B     |2222| 0003     |梱包        |0003      |梱包
13|NULL  |1111| NULL     |NULL        |0004      |出荷
14|NULL  |2222| NULL     |NULL        |0004      |出荷
15|NULL  |3333| NULL     |NULL        |0005      |検証

引用返信 編集キー/
■98134 / inTopicNo.11)  Re[10]: SQLの結合について
□投稿者/ 鏡月 (70回)-(2021/09/22(Wed) 16:25:59)
No98133 (魔界の仮面弁士 さん) に返信
> ■No98132 (鏡月 さん) に返信
>>WHERE 実績.指図ID = 'A'
>
> やはり条件が漏れていましたか。
> こうなると、当初の質問とは似て非なる問題になってしまいますよね。
>
>
> さて結局のところ、そのデータに対してどういう結果を求めているのでしょうか?
> 条件もデータも変わってしまったので、当初の質問内容からでは「やりたいこと」を判断できません。
>
>
> ひとまず WHERE 句が無ければ、FULL OUTER JOIN によって
> 下記の 15 行のデータになります。
>
> そこに WHERE 実績.指図ID = 'A' を加えれば、
> 1〜6 行目だけに絞り込まれるのは必然かと。
>
> 行|指図ID|品番|過去作業ID|過去作業内容|現在作業ID|現在作業内容
> --+------+----+----------+------------+----------+------------
> 1|A |1111| 0001 |洗浄 |0001 |洗浄
> 2|A |1111| 0002 |乾燥 |NULL |NULL
> 3|A |1111| 0003 |梱包 |0003 |梱包
> 4|A |3333| 0001 |洗浄 |NULL |NULL
> 5|A |3333| 0002 |乾燥 |0002 |乾燥
> 6|A |3333| 0003 |梱包 |NULL |NULL
> 7|B |1111| 0001 |洗浄 |0001 |洗浄
> 8|B |1111| 0002 |乾燥 |NULL |NULL
> 9|B |1111| 0003 |梱包 |0003 |梱包
> 10|B |2222| 0001 |洗浄 |0001 |洗浄
> 11|B |2222| 0002 |乾燥 |NULL |NULL
> 12|B |2222| 0003 |梱包 |0003 |梱包
> 13|NULL |1111| NULL |NULL |0004 |出荷
> 14|NULL |2222| NULL |NULL |0004 |出荷
> 15|NULL |3333| NULL |NULL |0005 |検証

大変申し訳ございませんでした。
指図IDをキーに検索し実績作業内容と現在のマスタ内の作業内容の差異について比較したいと考えております。
下記データのような値を出力することは可能でしょうか。

サンプル出力データ
行|指図ID|品番|過去作業ID|過去作業内容|現在作業ID|現在作業内容
--+------+----+----------+------------+----------+------------
1|A |1111| 0001 |洗浄 |0001 |洗浄
2|A |1111| 0002 |乾燥 |NULL |NULL
3|A |1111| 0003 |梱包 |0003 |梱包
4|NULL |1111| NULL |NULL |0004 |出荷
5|A |3333| 0001 |洗浄 |NULL |NULL
6|A |3333| 0002 |乾燥 |0002 |乾燥
7|A |3333| 0003 |梱包 |NULL |NULL
8|NULL |3333| NULL |NULL |0005 |検証


引用返信 編集キー/
■98135 / inTopicNo.12)  Re[11]: SQLの結合について
□投稿者/ 魔界の仮面弁士 (3185回)-(2021/09/22(Wed) 17:14:30)
No98133 (魔界の仮面弁士) に追記
> ひとまず WHERE 句が無ければ、FULL OUTER JOIN によって
> 下記の 15 行のデータになります。
> 
> そこに WHERE 実績.指図ID = 'A' を加えれば、
> 1〜6 行目だけに絞り込まれるのは必然かと。

たとえば、WITH 句あるいは副問い合わせを使って

 FROM 「12 件の 実績のうち、指図ID = 'A' で絞り込んだ 6 件」
 FULL OUTER JOIN 「マスタ全件 8 件」

という絞り込みにすれば、結果は 11 件になりますね。
先の No98133 の 15 行のデータと比較してみます。

行1: 抽出される(過去実績 A-1111-0001 は  A  なので対象、現在マスタ 1111-0001 がマップされる)
行2: 抽出される(過去実績 A-1111-0002 は  A  なので対象、現在マスタ 1111-0002 は無いので null 表記)
行3: 抽出される(過去実績 A-1111-0003 は  A  なので対象、現在マスタ 1111-0003 がマップされる)
行4: 抽出される(過去実績 A-3333-0001 は  A  なので対象、現在マスタ 3333-0001 は無いので null 表記)
行5: 抽出される(過去実績 A-3333-0002 は  A  なので対象、現在マスタ 3333-0002 がマップされる)
行6: 抽出される(過去実績 A-3333-0003 は  A  なので対象、現在マスタ 3333-0003 は無いので null 表記)
行7: 抽出対象外(過去実績 B-1111-0001 は 非A なので除外、現在マスタ 1111-0001 は既に行1にマップ済み)
行8: 抽出対象外(過去実績 B-1111-0002 は 非A なので除外、現在マスタ 1111-0002 はそもそも存在していない)
行9: 抽出対象外(過去実績 B-1111-0003 は 非A なので除外、現在マスタ 1111-0003 は既に行3にマップ済み)
行10: 抽出される(過去実績 B-2222-0001 は 非A⇒null 表記、現在マスタ 2222-0001 がマップされる)
行11: 抽出対象外(過去実績 B-2222-0002 は 非A なので除外、現在マスタ 2222-0002 はそもそも存在していない)
行12: 抽出される(過去実績 B-2222-0003 は 非A⇒null 表記、現在マスタ 2222-0003 がマップされる)
行13: 抽出される(過去実績 *-1111-0004 は無い⇒null 表記、現在マスタ 1111-0004 がマップされる)
行14: 抽出される(過去実績 *-2222-0004 は無い⇒null 表記、現在マスタ 2222-0004 がマップされる)
行15: 抽出される(過去実績 *-3333-0005 は無い⇒null 表記、現在マスタ 3333-0005 がマップされる)


■No98134 (鏡月 さん) に返信
> 指図IDをキーに検索し実績作業内容と現在のマスタ内の作業内容の差異について比較したいと考えております。
> 下記データのような値を出力することは可能でしょうか。

FULL JOIN にもかかわらず、抽出結果から 品番 = '2222' が消える理由を説明してください。

No98134 の行番号を 1'〜8' と表記して、
先の No98133 の 15 行のデータと比較してみると:

行1' ⇒ 行 1(過去実績 A-1111-0001、現在マスタ 1111-0001)
行2' ⇒ 行 2(過去実績 A-1111-0002、現在マスタなしで null)
行3' ⇒ 行 3(過去実績 A-1111-0003、現在マスタ 1111-0003)
行4' ⇒ 行13(過去実績なしで null 、現在マスタ 1111-0004)
行5' ⇒ 行 4(過去実績 A-3333-0001、現在マスタなしで null)
行6' ⇒ 行 5(過去実績 A-3333-0002、現在マスタ 3333-0002)
行7' ⇒ 行 6(過去実績 A-3333-0003、現在マスタなしで null)
行8' ⇒ 行15(過去実績なしで null 、現在マスタ 3333-0005)

引用返信 編集キー/
■98137 / inTopicNo.13)  Re[12]: SQLの結合について
□投稿者/ 魔界の仮面弁士 (3186回)-(2021/09/22(Wed) 17:27:05)
No98135 (魔界の仮面弁士) に追記
> ■No98134 (鏡月 さん) に返信
>>指図IDをキーに検索し実績作業内容と現在のマスタ内の作業内容の差異について比較したいと考えております。
>>下記データのような値を出力することは可能でしょうか。
> FULL JOIN にもかかわらず、抽出結果から 品番 = '2222' が消える理由を説明してください。

とりあえず、「指図ID = 'A' に該当した品番のみを対象とする」という条件にしてみました。
前提条件が不足しているので、やりたいことに合致しているかは分かりませんが。


WITH
  過去 AS (SELECT 指図ID, 品番, 作業ID, 作業内容 FROM 実績 WHERE 指図ID = 'A')
, 現在 AS (SELECT 品番, 作業ID, 作業内容 FROM マスタ
WHERE EXISTS(SELECT null FROM 過去 WHERE 過去.品番 = マスタ.品番))
SELECT
 過去.指図ID
,COALESCE(過去.品番,現在.品番) AS 品番
,過去.作業ID   AS 過去作業ID
,過去.作業内容 AS 過去作業内容
,現在.作業ID   AS 現在作業ID
,現在.作業内容 AS 現在作業内容
FROM 過去 FULL OUTER JOIN 現在
  ON 過去.品番 = 現在.品番 AND 過去.作業ID = 現在.作業ID
ORDER BY
 COALESCE(過去.品番,現在.品番)  
,COALESCE(過去.作業ID,現在.作業ID)

引用返信 編集キー/
■98138 / inTopicNo.14)  Re[13]: SQLの結合について
□投稿者/ 鏡月 (71回)-(2021/09/22(Wed) 20:34:38)
2021/09/24(Fri) 11:31:09 編集(投稿者)

No98137 (魔界の仮面弁士 さん) に返信
ご返信が遅くなってしまい申し訳ございません。

> 指図IDをキーに検索し実績作業内容と現在のマスタ内の作業内容の差異について比較したいと考えております。
> 下記データのような値を出力することは可能でしょうか。

FULL JOIN にもかかわらず、抽出結果から 品番 = '2222' が消える理由を説明してください。
→どのように抽出すれば良いのかいまいちわからなかったため、類似したデータが抽出できるFULL JOINを使用しておりました。
 FULL JOINで結合後、抽出条件によって対象データが出力できれば良いなと考えておりました。

> とりあえず、「指図ID = 'A' に該当した品番のみを対象とする」という条件にしてみました。
> 前提条件が不足しているので、やりたいことに合致しているかは分かりませんが。
→副問い合わせについての知識があまりなかったので、再度調べてみようかと思います。
 詳細なテストはまだできておりませんが検証環境では作成していただきましたSQLにて抽出することができましたのでこちらをベースに内容の確認をさせていただきます。

 前提条件が足らずいろいろとご迷惑をおかけして申し訳ございませんでした。
 また、長い間親切丁寧にご対応していただきありがとうございます。
 
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -