iT邦幫忙

1

SQL 一欄變多欄

sql
  • 分享至 

  • xImage

原本資料為是二欄位(Number/color),每欄資料如下表示
Number:A
color:紅、黃
Number:B
color:黑
Number:C
color:黃
Number:D
color:紅、黃、黑

想用sql查詢出來為四欄位(Number/紅/黃/黑), 每欄資料如下表示
Number:A
紅:Y
黃:Y
黑:
Number:B
紅:
黃:
黑:Y
Number:C
紅:
黃:Y
黑:
Number:D
紅:Y
黃:Y
黑:Y

wu2960 iT邦新手 3 級 ‧ 2022-11-17 10:05:03 檢舉
1.先拆解【、】相隔的字串
https://dotblogs.com.tw/wasichris/2017/12/29/030655

2.再使用 PIVOT 扭轉資料,由直列轉為橫向資料
https://dotblogs.com.tw/wasichris/2016/11/07/131258
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

4
純真的人
iT邦大師 1 級 ‧ 2022-11-17 10:13:01
最佳解答

不考慮color自由變動~若固定顏色如下~

declare @Tmp table(
	Number nvarchar(10)
	,color nvarchar(10)
)

insert into @Tmp
values('A','紅、黃')
,('B','黑')
,('C','黑')
,('D','紅、黃、黑')

select Number
,(case when CharIndex('紅',color) > 0 then 'Y' else '' end) as [紅]
,(case when CharIndex('黃',color) > 0 then 'Y' else '' end) as [黃]
,(case when CharIndex('黑',color) > 0 then 'Y' else '' end) as [黑]
from @Tmp

https://ithelp.ithome.com.tw/upload/images/20221117/20061369kIqwHApaNG.jpg

我加上Oracle寫法~

create table Tmp(
	Num VARCHAR2(10)
	,color VARCHAR2(50)
)
insert into Tmp(Num,color) values('A','紅、黃');
insert into Tmp(Num,color) values('B','黑');
insert into Tmp(Num,color) values('C','黑');
insert into Tmp(Num,color) values('D','紅、黃、黑');
select Num
,(case when instr(color,'紅') > 0 then 'Y' else ' ' end) as 紅
,(case when instr(color,'黃') > 0 then 'Y' else ' ' end) as 黃
,(case when instr(color,'黑') > 0 then 'Y' else ' ' end) as 黑
from Tmp

參考
https://dbfiddle.uk/cRGhWZEe

看更多先前的回應...收起先前的回應...
what0208 iT邦新手 5 級 ‧ 2022-11-17 10:31:38 檢舉

你好,我用出來會出現這種錯誤訊息。。
ORA-00923: 在應出現的位置找不到 FROM 關鍵字
00923. 00000 - "FROM keyword not found where expected"
會是因為我的資料為紅,黃
中間會有,嗎

what0208 iT邦新手 5 級 ‧ 2022-11-17 10:34:27 檢舉

我的是Oracle sql,會是因為不一樣的資料庫嗎

what0208
對~因為你沒有指出哪個資料庫~我就用Sql Server的SQL

what0208 iT邦新手 5 級 ‧ 2022-11-17 10:51:12 檢舉

請問Oracle的語法該怎麻串呢?

wu2960 iT邦新手 3 級 ‧ 2022-11-17 11:00:42 檢舉

我也以為是MSSQL,建議修改標題註明Oracle

what0208
加上Oracle寫法~

尼克 iT邦大師 1 級 ‧ 2022-11-17 13:07:38 檢舉

這個叫做 row to column

what0208 iT邦新手 5 級 ‧ 2022-11-17 13:10:44 檢舉

它的值可以完全一樣嗎,才給Y?
例如:
A紅黃,紅
B紅黃
C紅
會變成
A紅黃Y,紅Y
B紅黃Y,紅Y
C紅黃Y,紅Y
只要是有一樣的字就會被Y

what0208 iT邦新手 5 級 ‧ 2022-11-17 13:40:15 檢舉

像這樣https://dbfiddle.uk/3WZQ4JJE
C的部份就錯了,應該只會有一個Y才對,它的功能是像LIKE,是否=的?

what0208
可以用加上【、】來區隔單一顏色別~

select Num
,(case when instr('、' || color || '、','、紅黃、') > 0 then 'Y' else ' ' end) as 紅黃
,(case when instr('、' || color || '、','、紅、') > 0 then 'Y' else ' ' end) as 紅
from Tmp

https://dbfiddle.uk/qM5EELVv

what0208 iT邦新手 5 級 ‧ 2022-11-17 14:40:38 檢舉

我用這個方式可行了,不過為什麼是用'、紅黃、'而不是用'紅黃'
前面不是已經用、分開了嗎

那是因為避免模糊~才需要都加上逗號來區別唯一性~

西撒 iT邦新手 5 級 ‧ 2022-11-20 07:50:59 檢舉

資料後處理,比較推薦在伺服器用程式語言處理

不要在資料庫進行邏輯運算

0
johncoc
iT邦新手 3 級 ‧ 2022-11-17 10:55:17

提供一個 pivot 寫法
oracle輸入''會自動轉成null所以這邊就不做null判斷
如果樓主是要' ',再用null判斷即可(NVL)

https://dbfiddle.uk/ZELDweCl

SELECT *
FROM (
    SELECT Num, regexp_substr(color, '[^、]+', 1, level) color,'Y' Agg
    FROM (SELECT Num, color FROM test)
    CONNECT BY instr(color, '、', 1, level - 1) > 0
) t
PIVOT (
	MAX(Agg)
	FOR color IN ('紅' 紅, '黃' 黃, '黑' 黑)
) p
SELECT Num
    ,NVL(紅,' ') 紅
    ,NVL(黃,' ') 黃
    ,NVL(黑,' ') 黑
FROM (
    SELECT Num, regexp_substr(color, '[^、]+', 1, level) color,'Y' Agg
    FROM (SELECT Num, color FROM test)
    CONNECT BY instr(color, '、', 1, level - 1) > 0
) t
PIVOT (
	MAX(Agg)
	FOR color IN ('紅' 紅, '黃' 黃, '黑' 黑)
) p
看更多先前的回應...收起先前的回應...

測試失敗呢@@...
https://dbfiddle.uk/gAb_BVVh

johncoc iT邦新手 3 級 ‧ 2022-11-17 11:40:35 檢舉

名稱錯誤XD

johncoc iT邦新手 3 級 ‧ 2022-11-17 12:01:44 檢舉

修好了

what0208 iT邦新手 5 級 ‧ 2022-11-17 13:57:24 檢舉

Hi 我用這個方式執行不起來> <

johncoc iT邦新手 3 級 ‧ 2022-11-17 14:00:06 檢舉

是什麼錯誤?

what0208 iT邦新手 5 級 ‧ 2022-11-17 14:12:45 檢舉

ORA-00918: column ambiguously defined
因為我要SELECT出來的欄位會有很多個,再加入其它的欄位就會出錯。。

johncoc iT邦新手 3 級 ‧ 2022-11-17 14:18:03 檢舉

你要看一下select的資料表有沒有同樣的欄位名稱

what0208 iT邦新手 5 級 ‧ 2022-11-17 14:39:05 檢舉

哈有,因為我想合對出來的資料是不是有一致。我會再試一下這種方式,謝謝你們,讓我多了好多種使用方式。

我要發表回答

立即登入回答