【问题标题】:Split columns from single table and join as multiple columns on another从单个表中拆分列并作为多个列连接到另一个表中
【发布时间】:2018-05-01 15:14:04
【问题描述】:

我想将一个表中的列拆分为另一个表中的多个列

假设我想将 FoodAttributeTable 加入 FoodTable:

美食桌

+------------+-------+
|    Food    | Price |
+------------+-------+
| Strawberry |    10 |
| Broccoli   |    25 |
+------------+-------+

食物属性表

+------------+---------------+----------------+
|    Food    | AttributeName | AttributeValue |
+------------+---------------+----------------+
| Strawberry | Vitamin       | C              |
| Strawberry | Weight        | 15g            |
| Strawberry | Color         | Red            |
| Broccoli   | Vitamin       | B              |
| Broccoli   | Weight        | 70g            |
| Broccoli   | Color         | Green          |
+------------+---------------+----------------+

表格是:

美食桌

+------------+-------+---------+--------+-------+
|    Food    | Price | Vitamin | Weight | Color |
+------------+-------+---------+--------+-------+
| Strawberry |    10 | C       | 15g    | Red   |
| Broccoli   |    25 | B       | 70g    | Green |
+------------+-------+---------+--------+-------+

【问题讨论】:

  • 到目前为止你尝试过什么?然而,理想情况下,这不是数据库设计的正确方法。基于不同列的值,单个列应仅代表 1 个事物,而不是不同的事物。
  • 嗨,欢迎来到 SO。如果您可以发布 ddl 和示例数据以及所需的输出,我们可以提供帮助。这是一个很好的起点。 spaghettidba.com/2015/04/24/…

标签: sql-server split sql-server-2014 multiple-columns


【解决方案1】:

您可以使用如下所示的简单 PIVOT 查询。 查看官方MSDN documentation on PIVOT。

select 
Food,Price,Vitamin,Weight,Color
from
(
    select f.Food,f.Price,
     AttributeName  ,AttributeValue
    from
    FoodTable f join
    FoodAttributeTable fat on
    f.Food=fat.Food
)s
pivot
(max(AttributeValue) for AttributeName in (Vitamin,Weight,Color))
p

这里还有一个 live demo

【讨论】:

  • 像魅力一样工作!非常感谢
  • @titatovenaar 感谢您的确认!请接受我的回复作为正确答案,以便其他用户受益:知道答案有效并将问题标记为已回答。
【解决方案2】:

这是一个动态透视查询。因此,如果您的 FoodAttributeTable 属性是动态的,我只会推荐这个。

创建表格并插入数据

CREATE TABLE FoodAttributeTable(
    Food nvarchar(50) NULL,
    AttributeName nvarchar(50) NULL,
    AttributeValue nvarchar(50) NULL
) 

INSERT FoodAttributeTable (Food, AttributeName, AttributeValue) VALUES (N'Strawberry', N'Vitamin', N'C')    
INSERT FoodAttributeTable (Food, AttributeName, AttributeValue) VALUES (N'Strawberry', N'Weight', N'15g')    
INSERT FoodAttributeTable (Food, AttributeName, AttributeValue) VALUES (N'Strawberry', N'Color', N'Red')    
INSERT FoodAttributeTable (Food, AttributeName, AttributeValue) VALUES (N'Broccoli', N'Vitamin', N'B')    
INSERT FoodAttributeTable (Food, AttributeName, AttributeValue) VALUES (N'Broccoli', N'Weight', N'70g')    
INSERT FoodAttributeTable (Food, AttributeName, AttributeValue) VALUES (N'Broccoli', N'Color', N'Green')


CREATE TABLE FoodTable(
    Food nvarchar(50) NULL,
    Price decimal(18, 0) NULL
)

INSERT FoodTable (Food, Price) VALUES (N'Strawberry', N'10')    
INSERT FoodTable (Food, Price) VALUES (N'Broccoli', N'25')

查询

DECLARE @colsValues AS NVARCHAR(max) = Stuff((SELECT DISTINCT ',' + Quotename(fat.attributename)
         FROM   foodattributetable fat       
         FOR xml path(''), type).value('.', 'NVARCHAR(MAX)'), 1, 1, ''); 

DECLARE @query AS NVARCHAR(max) =  'SELECT     * 
                                    FROM       (SELECT * 
                                                FROM   foodattributetable 
                                                PIVOT(Max(attributevalue) 
                                                FOR attributename IN ('+ @colsValues +')) piv) fat
                                    INNER JOIN foodtable tb 
                                    ON         tb.food = fat.food';

EXECUTE(@query) 

输出

+------------+-------+---------+--------+------------+-------+
|    Food    | Color | Vitamin | Weight |    Food    | Price |
+------------+-------+---------+--------+------------+-------+
| Broccoli   | Green | B       | 70g    | Broccoli   |    25 |
| Strawberry | Red   | C       | 15g    | Strawberry |    10 |
+------------+-------+---------+--------+------------+-------+

演示:http://rextester.com/ATZF46215

【讨论】:

  • 我很好奇。因为以前的解决方案有效,但可能不是动态的。有时会添加新的食物或属性类型。是这样处理的吗?
  • 这是一个动态的 PIVOT 查询。所以,是的。我相信是这样。您可以添加新的食物、attributeName、AttributeValue 而不必更改查询。演示:rextester.com/AVS94472
猜你喜欢
  • 2010-10-20
  • 1970-01-01
  • 1970-01-01
  • 2011-05-05
  • 2016-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多