[英]Join a single column of value labels to multiple columns of values in another table in SQL
我有兩個表: Preferences
,它顯示學生的膳食偏好,以及Key
,它是理解每個膳食項目的每個值的關鍵。
Preferences:
| Student_ID | Student_Name | Meat | Vegetable | Drink | Dessert |
|------------|--------------|------|-----------|-------|---------|
| 1 | Jeff | 3 | 1 | 4 | 1 |
| 2 | Andrea | 1 | 1 | 3 | 1 |
| 3 | Allison | 3 | 2 | 7 | 1 |
| 4 | Randy | 1 | 1 | 4 | 2 |
| 5 | Carl | 2 | 5 | 2 | 2 |
| 6 | Bobby | 1 | 6 | 7 | 2 |
| 7 | Julie | 3 | 5 | 2 | 1 |
| 8 | Anna | 1 | 6 | 7 | 2 |
| 9 | Carlos | 1 | 6 | 2 | 2 |
| 10 | Roger | 2 | 4 | 2 | 1 |
| 11 | Pierre | 1 | 2 | 1 | 1 |
| 12 | Troy | 2 | 3 | 3 | 1 |
| 13 | David | 3 | 6 | 6 | 2 |
| 14 | Michaela | 1 | 4 | 5 | 2 |
| 15 | Rose | 1 | 4 | 6 | 1 |
| 16 | Anita | 3 | 6 | 6 | 2 |
| 17 | Connor | 3 | 3 | 3 | 1 |
| 18 | Eddie | 1 | 2 | 7 | 1 |
| 19 | Karen | 3 | 5 | 5 | 2 |
| 20 | Rachel | 3 | 2 | 2 | 1 |
| | | | | | |
Key:
| Item_Type | Item | Value |
|-----------|----------|-------|
| Meat | Chicken | 1 |
| Meat | Beef | 2 |
| Meat | Fish | 3 |
| Vegetable | Carrots | 1 |
| Vegetable | Peas | 2 |
| Vegetable | Corn | 3 |
| Vegetable | Broccoli | 4 |
| Vegetable | Zucchini | 5 |
| Vegetable | Eggplant | 6 |
| Drink | Water | 1 |
| Drink | Milk | 2 |
| Drink | Juice | 3 |
| Drink | Cola | 4 |
| Drink | Lemonade | 5 |
| Drink | Tea | 6 |
| Drink | Punch | 7 |
| Dessert | Cake | 1 |
| Dessert | Pie | 2 |
我試圖找出最有效的方法,將值標簽分配給Preferences
中來自Key
的單個Item
列的每列膳食項目值。 換句話說,我想JOIN
這兩個表來創建下表:
| Student_ID | Student_Name | Meat | Vegetable | Drink | Dessert |
|------------|--------------|---------|-----------|----------|---------|
| 1 | Jeff | Fish | Carrots | Cola | Cake |
| 2 | Andrea | Chicken | Carrots | Juice | Cake |
| 3 | Allison | Fish | Peas | Punch | Cake |
| 4 | Randy | Chicken | Carrots | Cola | Pie |
| 5 | Carl | Beef | Zucchini | Milk | Pie |
| 6 | Bobby | Chicken | Eggplant | Punch | Pie |
| 7 | Julie | Fish | Zucchini | Milk | Cake |
| 8 | Anna | Chicken | Eggplant | Punch | Pie |
| 9 | Carlos | Chicken | Eggplant | Milk | Pie |
| 10 | Roger | Beef | Broccoli | Milk | Cake |
| 11 | Pierre | Chicken | Peas | Water | Cake |
| 12 | Troy | Beef | Corn | Juice | Cake |
| 13 | David | Fish | Eggplant | Tea | Pie |
| 14 | Michaela | Chicken | Broccoli | Lemonade | Pie |
| 15 | Rose | Chicken | Broccoli | Tea | Cake |
| 16 | Anita | Fish | Eggplant | Tea | Pie |
| 17 | Connor | Fish | Corn | Juice | Cake |
| 18 | Eddie | Chicken | Peas | Punch | Cake |
| 19 | Karen | Fish | Zucchini | Lemonade | Pie |
| 20 | Rachel | Fish | Peas | Milk | Cake |
| | | | | | |
其中Preferences
中每個學生的每個膳食項目值都與Key
中單個Item
列中的相應標簽匹配。
這是一個單一連接的解決方案。
它是在 MySQL 中實現的,但只需稍作改動,它就可以在任何其他數據庫中實現。
select Preferences.Student_ID
,Preferences.Student_Name
,max(case `Key`.Item_Type when 'Meat' then `Key`.item end) as Meat
,max(case `Key`.Item_Type when 'Vegetable' then `Key`.item end) as Vegetable
,max(case `Key`.Item_Type when 'Drink' then `Key`.item end) as Drink
,max(case `Key`.Item_Type when 'Dessert' then `Key`.item end) as Dessert
from Preferences join `Key`on
`Key`.Item_Type = 'Meat' and `Key`.value = Preferences.Meat
or `Key`.Item_Type = 'Vegetable' and `Key`.value = Preferences.Vegetable
or `Key`.Item_Type = 'Drink' and `Key`.value = Preferences.drink
or `Key`.Item_Type = 'Dessert' and `Key`.value = Preferences.Dessert
group by Preferences.Student_ID, Preferences.Student_Name
order by Preferences.Student_ID
學生卡 | 學生姓名 | 肉 | 蔬菜 | 喝 | 甜點 |
---|---|---|---|---|---|
1 | 傑夫 | 魚 | 蘿卜 | 可樂 | 蛋糕 |
2 | 安德烈亞 | 雞 | 蘿卜 | 果汁 | 蛋糕 |
3 | 艾莉森 | 魚 | 豌豆 | 沖床 | 蛋糕 |
4 | 蘭迪 | 雞 | 蘿卜 | 可樂 | 餡餅 |
5 | 卡爾 | 牛肉 | 夏南瓜 | 牛奶 | 餡餅 |
6 | 鮑比 | 雞 | 茄子 | 沖床 | 餡餅 |
7 | 朱麗葉 | 魚 | 夏南瓜 | 牛奶 | 蛋糕 |
8 | 安娜 | 雞 | 茄子 | 沖床 | 餡餅 |
9 | 卡洛斯 | 雞 | 茄子 | 牛奶 | 餡餅 |
10 | 羅傑 | 牛肉 | 西蘭花 | 牛奶 | 蛋糕 |
11 | 皮埃爾 | 雞 | 豌豆 | 水 | 蛋糕 |
12 | 特洛伊 | 牛肉 | 玉米 | 果汁 | 蛋糕 |
13 | 大衛 | 魚 | 茄子 | 茶 | 餡餅 |
14 | 米凱拉 | 雞 | 西蘭花 | 檸檬水 | 餡餅 |
15 | 玫瑰 | 雞 | 西蘭花 | 茶 | 蛋糕 |
16 | 安妮塔 | 魚 | 茄子 | 茶 | 餡餅 |
17 | 康納 | 魚 | 玉米 | 果汁 | 蛋糕 |
18 | 埃迪 | 雞 | 豌豆 | 沖床 | 蛋糕 |
19 | 凱倫 | 魚 | 夏南瓜 | 檸檬水 | 餡餅 |
20 | 雷切爾 | 魚 | 豌豆 | 牛奶 | 蛋糕 |
這是一個基於unpivot 和 pivot的完整、非常精簡的 SQL Server 解決方案。
請注意,子查詢僅適用於數據透視語句,因為任何不屬於該語句的列都會成為隱式分組依據的一部分。
select *
from (select item
,food_type
,Student_ID
,Student_Name
from Preferences as p
unpivot (food for food_type in (Meat,Vegetable,Drink,Dessert)) as u
join food on food.value = u.food and food.Item_Type = u.food_type) as pu
pivot (max(item) for food_type in(Meat, Vegetable, Drink, Dessert)) as p
order by Student_ID
學生卡 | 學生姓名 | 肉 | 蔬菜 | 喝 | 甜點 |
---|---|---|---|---|---|
1 | 傑夫 | 魚 | 蘿卜 | 可樂 | 蛋糕 |
2 | 安德烈亞 | 雞 | 蘿卜 | 果汁 | 蛋糕 |
3 | 艾莉森 | 魚 | 豌豆 | 沖床 | 蛋糕 |
4 | 蘭迪 | 雞 | 蘿卜 | 可樂 | 餡餅 |
5 | 卡爾 | 牛肉 | 夏南瓜 | 牛奶 | 餡餅 |
6 | 鮑比 | 雞 | 茄子 | 沖床 | 餡餅 |
7 | 朱麗葉 | 魚 | 夏南瓜 | 牛奶 | 蛋糕 |
8 | 安娜 | 雞 | 茄子 | 沖床 | 餡餅 |
9 | 卡洛斯 | 雞 | 茄子 | 牛奶 | 餡餅 |
10 | 羅傑 | 牛肉 | 西蘭花 | 牛奶 | 蛋糕 |
11 | 皮埃爾 | 雞 | 豌豆 | 水 | 蛋糕 |
12 | 特洛伊 | 牛肉 | 玉米 | 果汁 | 蛋糕 |
13 | 大衛 | 魚 | 茄子 | 茶 | 餡餅 |
14 | 米凱拉 | 雞 | 西蘭花 | 檸檬水 | 餡餅 |
15 | 玫瑰 | 雞 | 西蘭花 | 茶 | 蛋糕 |
16 | 安妮塔 | 魚 | 茄子 | 茶 | 餡餅 |
17 | 康納 | 魚 | 玉米 | 果汁 | 蛋糕 |
18 | 埃迪 | 雞 | 豌豆 | 沖床 | 蛋糕 |
19 | 凱倫 | 魚 | 夏南瓜 | 檸檬水 | 餡餅 |
20 | 雷切爾 | 魚 | 豌豆 | 牛奶 | 蛋糕 |
我不確定您提到the most efficient way
,但是您可以執行四次inner join
,如下所示:
Select P.Student_ID, P.Student_Name,
K1.item as Meat, K2.item as Vegetable,K3.item as Drink, K4.item as Dessert
from Preferences P
inner Join Key_ K1 On (P.Meat=K1.Value_ and K1.Item_Type='Meat')
inner Join Key_ K2 On (P.Vegetable=K2.Value_ and K2.Item_Type='Vegetable')
inner Join Key_ K3 On (P.Drink=K3.Value_ and K3.Item_Type='Drink')
inner Join Key_ K4 On (P.Dessert=K4.Value_ and K4.Item_Type='Dessert')
order by P.Student_ID
請參閱db-fiddle 的演示。
另一種方法是執行兩個操作,首先是unpivot - 然后是內部連接。 不確定您是否要再次旋轉結果,但如果您這樣做了,我猜這將是第三次操作。
WITH CTE_UNPIVOT AS (
SELECT * FROM Preferences
UNPIVOT( VALUE for ITEM_TYPE in ( Meat, Veg, Drink, Dessert ))
),
CTE_MAPPED AS (
SELECT * FROM CTE_UNPIVOT
INNER JOIN Key
ON CTE_UNPIVOT.ITEM_TYPE = Key.ITEM_TYPE
)
SELECT * FROM CTE_MAPPED;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.