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

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

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

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

SQL

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

データベース設計

データベース設計はデータベースの論理的や物理的な部分を特定する工程です。

Q&A

解決済

1回答

786閲覧

移行におけるマルチカラムアトリビュートの解消方法について

kakutus

総合スコア2

SQL Server

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

SQL

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

データベース設計

データベース設計はデータベースの論理的や物理的な部分を特定する工程です。

0グッド

0クリップ

投稿2022/06/01 05:01

SQLアンチパターンの1つであるマルチカラムアトリビュートを解決するためにテーブルを作り直してデータを移行する場合、カーソル処理以外だとどのような移行方法がありますでしょうか。

実現したいこと

以下のテーブルAを、テーブルBに作り直すとします。

テーブルA

氏名ID住所1住所2住所3
0001A県B市C町
0002D県E郡NULL

テーブルB

氏名ID住所ID住所
00011A県
00012B市
00013C町
00021D県
00022E郡

※NULLのデータは移行しない

該当のソースコード

移行するためのSQLを実装するとき、1番最初に思い付いたのは以下のようなカーソル処理での場合分けですが、
1万件以上のデータを扱うと処理が極端に重くなってしまいます。

SQLServer

1 2 DECLARE @NameID INT; 3 DECLARE crTriggerList CURSOR 4 FOR 5 SELECT [氏名ID] 6 FROM テーブルA 7 8 OPEN crTriggerList; 9 10 FETCH NEXT FROM crTriggerList 11 INTO @NameID 12 13 WHILE @@FETCH_STATUS = 0 14 BEGIN 15 DECLARE @Address1 INT --住所1 16 DECLARE @Address2 INT --住所2 17 DECLARE @Address3 INT --住所3 18 19 SELECT 20 @Address1 = 住所1 21 ,@Address2 = 住所2 22 ,@Address3 = 住所3 23 FROM テーブルA 24 WHERE 氏名ID = @NameID --氏名IDに紐づく住所を変数に代入 25 26 27 IF((@Address1 IS NOT NULL) --住所1がNULLでなければ住所IDを1として移行 28 BEGIN 29 INSERT INTO テーブルB 30 (氏名ID,住所ID,住所) 31 SELECT 32 氏名ID 33 ,'1' 34 ,住所1 35 FROM テーブルA 36 WHERE 氏名ID = @NameID 37 END 38 39 IF((@Address2 IS NOT NULL) --住所2がNULLでなければ住所IDを2として移行 40 BEGIN 41 INSERT INTO テーブルB 42 (氏名ID,住所ID,住所) 43 SELECT 44 氏名ID 45 ,'2' 46 ,住所2 47 FROM テーブルA 48 WHERE 氏名ID = @NameID 49 END 50 51 IF((@Address3 IS NOT NULL) --住所3がNULLでなければ住所IDを3として移行 52 BEGIN 53 INSERT INTO テーブルB 54 (氏名ID,住所ID,住所) 55 SELECT 56 氏名ID 57 ,'3' 58 ,住所3 59 FROM テーブルA 60 WHERE 氏名ID = @NameID 61 END 62 63 64 FETCH NEXT FROM crTriggerList 65 INTO @NameID 66 67 END 68 69 CLOSE crTriggerList; 70 DEALLOCATE crTriggerList;

カーソル処理を使わずにこのような移行が出来る方法がもしあるのであれば、教えていただきたいです。
よろしくお願いします。

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

Microsoft SQL Server Management Studio 18
Microsoft SQL Server 2019 (RTM-GDR) (KB4583458) - 15.0.2080.9 (X64) Nov 6 2020 16:50:01 Copyright (C) 2019 Microsoft Corporation Enterprise Edition (64-bit) on Windows Server 2019 Datacenter 10.0 <X64> (Build 17763: ) (Hypervisor)

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

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

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

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

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

guest

回答1

0

ベストアンサー

準備。

sql

1-- drop table test; 2create table test ( 3 name text, 4 addr1 text, 5 addr2 text, 6 addr3 text 7 ); 8 9insert into test values 10 ('0001','A県','B市','C町'), 11 ('0002','D県','E郡',NULL) 12 ;

移行。

sql

1drop table test2; 2create table test2 (name text, addrId int, addr text); 3 4delete from test2; 5insert into test2 6 select * from ( 7 select name, 1, addr1 as addr from test 8 union select name, 2, addr2 as addr from test 9 union select name, 3, addr3 as addr from test 10 ) as hoge 11 where addr is not null; 12 13select * from test2;

結果。

nameaddridaddr
00013C町
00011A県
00012B市
00021D県
00022E郡

投稿2022/06/01 05:27

shiketa

総合スコア3971

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問