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

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

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

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

Q&A

解決済

2回答

714閲覧

[SQL Server]列方向のデータ結合

bose

総合スコア10

SQL Server

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

0グッド

0クリップ

投稿2018/03/08 02:46

以下のカンマ区切りのデータを使って列方向のデータを結合したテーブルを作りたいです。
※使用しているものは SQL Server 2012 です。

【カンマ区切りデータ】
declare @IDs varchar(100) = '1,2,3'--商品ID
declare @Quantities varchar(100) = '10,20,30'--上記商品IDに対応する数

【最終的に欲しいテーブル】

商品ID
110
220
330

【やったこと】
カンマ区切りデータから2つのテーブルを作る(カンマ区切り -> テーブル にする関数を作成)
※下記、上手く表示できておりませんが。。。

商品ID
1
2
3
10
20
30

レコード数分のループを回して、各テーブルのループ数分のレコードを取得して、
その結果をインサートする方法は思いついたのですが、もっとスマートな方法があるだろうと思い質問しました。
※列同士がくっつけばいいだけなのに。。。

declare @IDs varchar(100) = '1,2,3'--商品ID
declare @Quantities varchar(100) = '10,20,30'--上記商品IDに対応する数

declare @TID table (nID int)
declare @TQuantity table (nQuantity int)
declare @TOrder table (
nID int,
nQuantity int
)

insert into @TID
select cast(A.str as int) from カンマ区切り -> テーブル にする関数 as A

declare @CountID int = (select count(*) from @TID)

insert into @TQuantity
select cast(B.str as int) from カンマ区切り -> テーブル にする関数 as B

declare @CountQuantity int = (select count(*) from @TQuantity)

if @CountID <> @CountQuantity
begin
--error
select 'error'
end

declare @Count int = 1

while @Count <= @CountID
begin

insert into @TOrder values ( (select nID from ( select nID, row_number() over (order by nID) as RowNumID from @TID ) as C where RowNumID = @Count), (select nQuantity from ( select nQuantity, row_number() over (order by nQuantity) as RowNumQuantity from @TQuantity ) as D where RowNumQuantity = @Count) ) set @Count = @Count + 1

end

-- 最終的に欲しい形にはなったが・・・
select * from @TOrder

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

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

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

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

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

guest

回答2

0

カンマ区切り -> テーブル にする関数 がすでにあるなら、それが返すテーブルに row_number() などで適当なIDを付けて、その付けたID同士で join するのが簡単ですかねぇ。

sql

1select 2 T1.nID, 3 T2.nQuantity 4from ( 5 select 6 row_number() over (order by cast(A.str as int)) rownum, 7 cast(A.str as int) nID 8 from [カンマ区切り -> テーブル にする関数](@IDs, ',') A 9) T1 inner join ( 10 select 11 row_number() over (order by cast(B.str as int)) rownum, 12 cast(B.str as int) nQuantity 13 from [カンマ区切り -> テーブル にする関数](@Quantities, ',') B 14) T2 on T1.rownum=T2.rownum

カンマ区切り -> テーブル にする関数 がないので動作確認できていません

投稿2018/03/08 03:26

alg

総合スコア2019

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

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

bose

2018/03/09 00:46

ご回答ありがとうございます! すごく為になりました!
guest

0

ベストアンサー

コードはブロックで括ってくださいね。
「なんの情報も無しに結合する」というコト自体が「データベース的な考えではない」と思います。

sql

1declare @IDs varchar(100) = '1,2,3'--商品ID 2declare @Quantities varchar(100) = '10,20,30'--上記商品IDに対応する数

そもそもこういう風になっている事自体が間違いだと思います。

sql

1declare @Datas varchar(MAX) = '1@10,2@20,3@30'

最悪こんな感じで「ID[1]が[10]個ある」みたいな感じで
ある程度関連性を持たせたデータにすべきだと思います。

無理やりやるとして自分ならテーブル値関数でこういうのを作って

sql

1SET ANSI_NULLS ON 2GO 3 4SET QUOTED_IDENTIFIER ON 5GO 6create FUNCTION [dbo].[utf_Split] 7( 8 @String nvarchar(max), 9 @Delimiter nvarchar(10) 10) 11RETURNS TABLE 12AS 13RETURN 14( 15 WITH Split(stpos,endpos,times) 16 AS( 17 SELECT 0 AS stpos,CHARINDEX(@Delimiter,@String) AS endpos,1 as times 18 UNION ALL 19 SELECT cast(endpos+1 as int),CHARINDEX(@Delimiter,@String,endpos+1),times+1 20 FROM Split 21 WHERE endpos > 0 22 ) 23 SELECT times as Id 24 ,SUBSTRING(@String,stpos,COALESCE(NULLIF(endpos,0),LEN(@String)+1)-stpos) as Data 25 ,stpos,endpos,max(times) over() as times 26 FROM Split 27 where endpos is not null 28)

行数をIDとして一致させて実行します。

sql

1select * from [dbo].[utf_Split]('1,2,3',',') 2select * from [dbo].[utf_Split]('10,20,30',',') 3 4select A.Data as 商品コード 5 ,B.Data as 個数 6from ( 7 select * from [dbo].[utf_Split]('1,2,3',',') 8) as A 9 inner join ( 10 select * from [dbo].[utf_Split]('10,20,30',',') 11 ) as B on B.Id=A.Id 12 13-- もちろんこれでもOKです 14select A.Data as 商品コード 15 ,B.Data as 個数 16from [dbo].[utf_Split]('1,2,3',',') as A 17 inner join [dbo].[utf_Split]('10,20,30',',') as B on B.Id=A.Id

↓実行結果
実行結果

投稿2018/03/08 03:13

編集2018/03/08 04:30
sousuke

総合スコア3828

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

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

bose

2018/03/09 00:47

ご回答ありがとうございます! また、色々なことをご教授ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問