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

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

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

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

SQL

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

Q&A

解決済

1回答

1812閲覧

SQL文で複数カラム同士の値一致件数を取得したい

hqqq

総合スコア4

SQL Server

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

SQL

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

0グッド

0クリップ

投稿2020/09/30 06:36

SQLServer2012+C#にてデータベースアプリを構築しております。

AテーブルとBテーブルがあり、内容はそれぞれ以下です。
■Aテーブル
ID  食材1    食材2    食材3    食材4
1   人参     じゃがいも  肉

■Bテーブル
ID  食材1    食材2    食材3    食材4
1   なす     人参     人参     肉

この2つのテーブルを「ID」で紐づけて、食材の一致数を抽出したく思っております。

調べた結果、以下のようなやり方を見つけました。

方法1
※該当文字列を削除し、その削除桁数からいくつ含まれていたかを割り出す方法のようです。

select ID, ( select (len(A.食材1+A.食材2+A.食材3+A.食材4)-len(replace(A.食材1+A.食材2+A.食材3+A.食材4, B.食材1, ''))) / len(B.食材1) ) as CNT1 from A INNER JOIN B ON A.ID = B.ID

方法2
※単純に全パターン比較

select ID, ( CASE WHEN A.食材1 = B.食材1 THEN 1 ELSE 0 END AS A1_B1 + CASE WHEN A.食材1 = B.食材2 THEN 1 ELSE 0 END AS A1_B2 + CASE WHEN A.食材1 = B.食材3 THEN 1 ELSE 0 END AS A1_B3 + CASE WHEN A.食材1 = B.食材4 THEN 1 ELSE 0 END AS A1_B4 + CASE WHEN A.食材2 = B.食材1 THEN 1 ELSE 0 END AS A2_B1 + CASE WHEN A.食材2 = B.食材2 THEN 1 ELSE 0 END AS A2_B2 + CASE WHEN A.食材2 = B.食材3 THEN 1 ELSE 0 END AS A2_B3 + CASE WHEN A.食材2 = B.食材4 THEN 1 ELSE 0 END AS A2_B4 + CASE WHEN A.食材3 = B.食材1 THEN 1 ELSE 0 END AS A3_B1 + CASE WHEN A.食材3 = B.食材2 THEN 1 ELSE 0 END AS A3_B2 + CASE WHEN A.食材3 = B.食材3 THEN 1 ELSE 0 END AS A3_B3 + CASE WHEN A.食材3 = B.食材4 THEN 1 ELSE 0 END AS A3_B4 + CASE WHEN A.食材4 = B.食材1 THEN 1 ELSE 0 END AS A4_B1 + CASE WHEN A.食材4 = B.食材2 THEN 1 ELSE 0 END AS A4_B2 + CASE WHEN A.食材4 = B.食材3 THEN 1 ELSE 0 END AS A4_B3 + CASE WHEN A.食材4 = B.食材4 THEN 1 ELSE 0 END AS A4_B4 ) AS CNT1 from A INNER JOIN B ON A.ID = B.ID

方法1はパフォーマンス的に遅い、という記事を見かけたのですが、
他に同じ結果を取得する方法(関数?)のようなものはあるのでしょうか?

ちなみにEXCELでは
COUNTIF関数でAテーブルの食材1~4の範囲を指定すると簡単にカウントできます。
値をBテーブルの食材1~4で4回行うと、AテーブルとBテーブルの食材一致数が算出できます。
それを同じことをやりたいのです。

分かるかたいらっしゃいましたら宜しくお願い致します。

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

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

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

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

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

gentaro

2020/09/30 06:43

そもそもですが「食材1」「食材2」というようなカラムの持たせ方を良しとするようなDB設計は聞いたことがありません。 このように横に持たせるのではなく、行としてそれぞれを区別していれば、簡単に解決できる問題です。
hqqq

2020/09/30 07:31

そうですよね。。横の項目を集計しなければならない設計は見かけないですよね。 元がエクセルデータですので、そのままできないものか、何かCOUNTIFのような関数が無いか、等と期待してしまいました。 後々困るのも仰る通りですので、今回はシンプルに行で持つように変更してみます。 ありがとうございました。
sazi

2020/09/30 07:38 編集

unionもしくはvalues()を活用すればできそうな気が。
guest

回答1

0

自己解決

コメント欄にも記載しましたが、比較・カウント対象の値をカラムで持つのは現実的ではなさそうですので
テーブル設計を変更することにしました。

投稿2020/09/30 07:33

hqqq

総合スコア4

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問