iT邦幫忙

2

SQL 列出所有組合

  • 分享至 

  • xImage

請教有人會寫這種SQL嗎?
table columns: (menu, option_type, option_val)
values:
(1, 'A', '1')
(1, 'A', '2')
(2, 'A', '1')
(2, 'A', '2')
(2, 'B', '1')
(2, 'B', '2')
(3, 'A', '1')
(3, 'A', '2')
(3, 'B', '1')
(3, 'B', '2')
(3, 'C', '1')
(3, 'C', '2')
希望產生output如:
menu desc
1 A1
1 A2
2 A1 B1
2 A1 B2
2 A2 B1
2 A2 B2
3 A1 B1: C1
3 A1 B1: C2
3 A1 B2: C1
3 A1 B2: C2
3 A2 B1: C1
3 A2 B1: C2
3 A2 B2: C1
3 A2 B2: C2

求教。感謝!!

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
3
pilipala
iT邦新手 2 級 ‧ 2023-12-29 23:45:56
最佳解答

用 TSQL CTE 跑遞迴,參考看看

CREATE TABLE Temp (
	menu smallint , 
	option_type char(1) , 
	option_val char(1));

INSERT INTO Temp VALUES
(1, 'A', '1') , (1, 'A', '2'),
(2, 'A', '1') , (2, 'A', '2'), (2, 'B', '1'), (2, 'B', '2'),
(3, 'A', '1') , (3, 'A', '2') , (3, 'B', '1') , (3, 'B', '2') , (3, 'C', '1') , (3, 'C', '2');

; 
WITH CTE AS
(
	SELECT 
		menu , 
		option_type , 
		option_val , 
		CAST(option_type + option_val AS varchar(8000)) AS Memo ,
		CAST(1 as int) AS Stat
	FROM Temp
	UNION ALL
	SELECT 
		T2.menu , 
		T2.option_type , 
		T2.option_val ,
		T1.Memo + '_' + T2.option_type + T2.option_val ,
		CAST(Stat + 1 as int) AS Stat
	FROM Temp AS T2
		JOIN CTE AS T1 ON T2.menu = T1.menu 
							AND T2.option_type > T1.option_type
)
SELECT 
	F1.* 
FROM CTE AS F1
	JOIN
		(
			SELECT 
				menu , 
				COUNT(DISTINCT option_type) AS Stat
			FROM Temp
			GROUP BY menu 
		) AS F2 ON F1.menu = F2.menu 
					AND F1.stat = F2.stat
ORDER BY menu , memo

DROP TABLE IF EXISTS Temp

TSQL 語法連結

你的迴圈方式不錯~
增加第4層也會帶出~

(4, 'A', '1')
(4, 'A', '2')

https://dbfiddle.uk/TEIbaLSt

Amigo iT邦新手 5 級 ‧ 2024-01-03 16:57:52 檢舉

原來有這種語法~感謝!

minhome iT邦新手 5 級 ‧ 2024-01-26 14:52:06 檢舉

感謝

1
asd3733653
iT邦新手 2 級 ‧ 2023-12-29 17:42:55
-- 查詢結果
SELECT
    t1.menu,
    CONCAT(t1.option_type, t1.option_val) AS menu_desc
FROM
    your_table t1
WHERE
    t1.option_type = 'A' and t1.menu = 1

UNION

SELECT
    t1.menu,
    CONCAT(t1.option_type, t1.option_val, ',', t2.option_type, t2.option_val) AS menu_desc
FROM
    your_table t1
JOIN your_table t2 ON t1.menu = t2.menu AND t1.option_type = 'A' AND t2.option_type = 'B'
WHERE t1.menu = 2

UNION

SELECT
    t1.menu,
    CONCAT(t1.option_type, t1.option_val, ',', t2.option_type, t2.option_val, ',', t3.option_type, t3.option_val) AS menu_desc
FROM
    your_table t1
JOIN your_table t2 ON t1.menu = t2.menu AND t1.option_type = 'A' AND t2.option_type = 'B'
JOIN your_table t3 ON t2.menu = t3.menu AND t2.option_type = 'B' AND t3.option_type = 'C'
ORDER BY
    menu,
    menu_desc;

Amigo iT邦新手 5 級 ‧ 2024-01-03 16:44:37 檢舉

謝謝。但實際上不知有幾階,所以有困難

minhome iT邦新手 5 級 ‧ 2024-01-26 14:52:25 檢舉

謝謝

5
一級屠豬士
iT邦大師 1 級 ‧ 2023-12-29 22:41:34
看更多先前的回應...收起先前的回應...

果然加上這兩筆不會再增加@@...

(4, 'A', '1'),(4, 'A', '2'),
(4, 'B', '1'),(4, 'B', '2');
rogeryao iT邦超人 8 級 ‧ 2023-12-29 22:53:09 檢舉

這是個很奇怪的問題....

只有起始條件跟結果
完全沒有描述演算的邏輯...(如果他臨時又補了一個超乎預期的結果...那就...)

終究,你把他搞出來了...
還是給你拍拍手...

分段做cross join

rogeryao iT邦超人 8 級 ‧ 2023-12-29 23:08:50 檢舉

Good ....

我第一個想法也是...cross join...
只是...只是...年紀大了...
就看人表演比較實在...

我也是那種找工作~沒有公司敢收的年齡了(中高齡)~
反正撐完25年資~65歲領到就閃~
目前就玩玩SQL打發無聊的人生༼ つ ◕_◕ ༽つ

rogeryao iT邦超人 8 級 ‧ 2023-12-29 23:43:49 檢舉

屁啦...
社會就需要你這種...有衝勁...就幹勁的年輕人...
你都想退...

好吧...
我先退...

/images/emoticon/emoticon01.gif

Amigo iT邦新手 5 級 ‧ 2024-01-03 16:46:59 檢舉

實際上不知有幾階,但還是謝謝你!

0
純真的人
iT邦大師 1 級 ‧ 2023-12-30 22:54:38

引用pilipala的SQL程式碼
配合版主的結果顯示XD....

;WITH CTE AS
(
	SELECT 
		menu , 
		option_type , 
		option_val , 
		CAST(option_type + option_val AS varchar(8000)) AS Memo ,
		CAST(1 as int) AS Stat
	FROM Temp
	UNION ALL
	SELECT 
		T2.menu , 
		T2.option_type , 
		T2.option_val ,
		T1.Memo 
        + (case when Stat + 1 = 3 then ': ' else ' ' end)
        + T2.option_type + T2.option_val ,
		CAST(Stat + 1 as int) AS Stat
	FROM Temp AS T2
		JOIN CTE AS T1 ON T2.menu = T1.menu 
							AND T2.option_type > T1.option_type
)
SELECT F1.menu
,F1.Memo [desc]
FROM CTE AS F1
	JOIN
		(
			SELECT 
				menu , 
				COUNT(DISTINCT option_type) AS Stat
			FROM Temp
			GROUP BY menu 
		) AS F2 ON F1.menu = F2.menu 
					AND F1.stat = F2.stat
ORDER BY menu , memo

https://dbfiddle.uk/e_Q1P-QF

https://ithelp.ithome.com.tw/upload/images/20231230/20061369JHiIVYnJVX.png

Amigo iT邦新手 5 級 ‧ 2024-01-03 16:59:18 檢舉

謝謝!!

我要發表回答

立即登入回答