🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
SQL Server

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

SQL

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

Q&A

解決済

2回答

441閲覧

複数のキー項目で合致の無い場合、キー項目を減らして合致する行を探したい

退会済みユーザー

退会済みユーザー

総合スコア0

SQL Server

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

SQL

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

0グッド

0クリップ

投稿2019/10/26 05:19

編集2019/10/26 10:18

前提・実現したいこと

SQL Server 2014 についての質問です。
実データの入ったテーブル(以下コードでいうDataTable)と、それらに関わる設定値的な内容が入ったテーブル(以下コードで言うSettings)の2つを用意し、
・それぞれのcode1とcode2とcode3が合致する行を
・上記で合致するものがなければ、code1とcode2が合致する行を
・上記で合致するものがなければ、code1が合致する行を
取得(結合)したいと思っています。

発生している問題

以下のようなクエリなどを書いてみましたが、データ2・データ3・データ4は複数のSettings行が合致してしまい、希望通りに行きませんでした。
何かいい方法はありませんでしょうか。

該当のソースコード

SQL

1-- DataTableに対応する設定内容が定義されているテーブル 2CREATE TABLE Settings 3 ([code1] varchar(2) NOT NULL, [code2] varchar(3), [code3] varchar(4), [status1] varchar(30)) 4; 5INSERT INTO Settings 6 ([code1], [code2], [code3], [status1]) 7VALUES 8 ('01', '', '', '設定01'), -- 設定1 9 ('01', '001', '', '設定001'), -- 設定2 10 ('01', '001', '0002', '設定0002'), -- 設定3 11 ('01', '001', '0003', '設定0003') -- 設定4 12; 13 14-- 3つのキーコードを持つテーブル 15-- code1・code2は必ず値が入る想定。 16CREATE TABLE DataTable 17 ([code1] varchar(2) NOT NULL, [code2] varchar(3) NOT NULL, [code3] varchar(4)) 18; 19INSERT INTO DataTable 20 ([code1], [code2], [code3]) 21VALUES 22 ('01', '111', '1111'), -- データ1 23 ('01', '001', '2222'), -- データ2 24 ('01', '001', '3333'), -- データ3 25 ('01', '001', '0003') -- データ4 26-- : 27-- (略) 28-- : 29; 30

期待する結果は以下です。
・データ1 → 設定1が紐付く
・データ2 → 設定2が紐付く
・データ3 → 設定2が紐付く
・データ4 → 設定4が紐付く

試してみたクエリ1

SQL

1SELECT dt.code1,dt.code2,dt.code3,st.status1 FROM DataTable AS dt 2LEFT JOIN Settings AS st 3ON 4 dt.code1=st.code1 5 and (dt.code2=st.code2 OR st.code2='') 6 and (dt.code3=st.code3 OR st.code3='') 7;

試してみたクエリ2

SQL

1SELECT dt.code1,dt.code2,dt.code3,st.status1 FROM DataTable AS dt 2LEFT JOIN Settings AS st 3ON 4 dt.code1=st.code1 5 and st.code2 = case when dt.code2=st.code2 then dt.code2 else '' end 6 and st.code3 = case when dt.code3=st.code3 then dt.code3 else '' end 7; 8

実際は件数の多いデータになりますので、できるだけ軽く処理できればと思っているのですが…

よろしくお願いします。

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

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

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

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

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

guest

回答2

0

1行だけ欲しいなら

SQL

1SELECT TOP(1) * FROM DataTable AS dt 2LEFT JOIN Settings AS st 3ON 4 dt.code1 = st.code1 5ORDER BY 6 CASE WHEN dt.code2 = st.code2 THEN -2 END 7 + CASE WHEN dt.code3 = st.code3 THEN -3 END

速度が欲しいならストアドでゴリゴリかな?

コメントを受けての追記

SQL

1SELECT dt.*, 2( 3 SELECT TOP(1) st.status1 4 FROM Settings AS st 5 WHERE dt.code1 = st.code1 6 ORDER BY 7 CASE WHEN dt.code2 = st.code2 THEN -2 END 8 + CASE WHEN dt.code3 = st.code3 THEN -3 END 9) AS Setting 10FROM DataTable AS dt

投稿2019/10/26 09:35

編集2019/10/26 10:01
hihijiji

総合スコア4152

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

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

退会済みユーザー

退会済みユーザー

2019/10/26 09:47

早速のご回答ありがとうございます! DataTableの1行ごとにSettingsの1行を紐付けたいのですが、SELECT文1文で実現は難しいのでしょうか。
hihijiji

2019/10/26 10:01

追記しました。 こんなのでしょうか?
退会済みユーザー

退会済みユーザー

2019/10/26 10:22 編集

追記ありがとうございます! 実行してみたのですが、結果が全部「設定1」が紐付いてしまうようです。 以下のような結果を期待しています。 データ1 → 設定1が紐付く。 データ2 → 設定2が紐付く。 データ3 → 設定2が紐付く。 データ4 → 設定4が紐付く。 記載不足で申し訳ないです。(本文にも追記しました。) またお知恵を拝借できれば幸いです。 よろしくお願いします。
guest

0

ベストアンサー

詳しい方にご助言いただき、なんとかやりたいことを実現することができました。
随分と長くなってしまいますが…^^;

SQL(SQLServer)

1-- 1つめの条件に合致するものを取得 2select '条件1' as '合致条件', dt.code1 as code1, dt.code2 as code2, dt.code3 as code3, st.status1 3from DataTable as dt 4 inner join Settings as st 5 on 6 dt.code1 = st.code1 7 and dt.code2 = st.code2 8 and dt.code3 = st.code3 9-- 2つめの条件に合致するものを取得・結合 10union all 11select '条件2' as '合致条件', dt.code1 as code1, dt.code2 as code2, dt.code3 as code3, st.status1 12from DataTable as dt 13 inner join Settings as st 14 on 15 dt.code1 = st.code1 16 and dt.code2 = st.code2 17 and st.code2 <> '' 18 and st.code3 = '' 19where 20 -- 1つめの条件に合致するものを除外 21 not exists( 22 select 'X' from DataTable as dt_ex 23 inner join Settings as st_ex 24 on 25 dt.code1 = dt_ex.code1 26 and dt.code2 = dt_ex.code2 27 and dt.code3 = dt_ex.code3 28 and dt_ex.code1 = st_ex.code1 29 and dt_ex.code2 = st_ex.code2 30 and dt_ex.code3 = st_ex.code3 31 ) 32-- 3つめの条件に合致するものを取得・結合 33union all 34select '条件3' as '合致条件', dt.code1 as code1, dt.code2 as code2, dt.code3 as code3, st.status1 35from DataTable as dt 36 inner join Settings as st 37 on 38 dt.code1 = st.code1 39 and st.code2 = '' 40 and st.code3 = '' 41where 42 -- 1つめの条件に合致するものを除外 43 not exists( 44 select 'X' from DataTable as dt_ex 45 inner join Settings as st_ex 46 on 47 dt.code1 = dt_ex.code1 48 and dt.code2 = dt_ex.code2 49 and dt.code3 = dt_ex.code3 50 and dt_ex.code1 = st_ex.code1 51 and dt_ex.code2 = st_ex.code2 52 and dt_ex.code3 = st_ex.code3 53 ) 54 and 55 -- 2つめの条件に合致するものを除外 56 not exists( 57 select 'X' from DataTable as dt_ex 58 inner join Settings as st_ex 59 on 60 dt.code1 = dt_ex.code1 61 and dt.code2 = dt_ex.code2 62 and dt.code3 = dt_ex.code3 63 and dt_ex.code1 = st_ex.code1 64 and dt_ex.code2 = st_ex.code2 65 and st_ex.code2 <> '' 66 and st_ex.code3 = '' 67 ) 68;

ご回答くださったhihijiji様、ならびに閲覧いただきました方々、お忙しい中お時間をいただきありがとうございました。
お騒がせ致しました。

別の方法などがあれば、ご教示いただけますと幸いです。
何かありましたら、その時はまた何卒よろしくお願い致します。

投稿2019/10/28 13:34

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問