如何在列元素具有多个数据时动态创建新列

时间:2016-01-22 16:22:57

标签: sql sql-server

我在选择数据时尝试动态添加新表,让我们说我的sql数据库有

Food       ingredients
----------------------
sandwich   Bread
sandwich   Butter
sandwich   Jam

但我不希望它在我使用select命令时显示,我希望它看起来像这样

Food       ingredients      ingredients2       ingredients3
------------------------------------------------------------
sandwich   Bread            Butter             Jam

是否可以这样做?

请教给我

3 个答案:

答案 0 :(得分:0)

我会创建三个表。 FoodIngredientsFood_Ingredients

Food应该看起来像......

FoodID     FoodName 
  1        sandwich
  2        Omelet 

FoodID设为主键

Ingredient应该看起来像......

IngredientID    IngredientName
     1           Bread
     2           Butter
     3           Jam
     4           Egg
     5           Oil

制作IngredientID主键。

最后Food_Ingredients应该看起来像

FoodID   IngredientID
   1         1
   1         2
   1         3
   2         4
   2         2

将这两列列为FoodIngredient表的外键。

答案 1 :(得分:0)

按照M.Ali的回答建议查看数据库设计可能是一个好主意,但如果您只是想以某种方式检索数据,那么下面的查询应该适合您。请注意,它不是动态的,因此如果您需要更多列,则必须手动添加它们。但是,有可能以动态的方式生成列。

select food, ingredient1, ingredient2, ingredient3
from (
    select 
       food,
       ingredients, 
       concat('ingredient', row_number() over (partition by food order by ingredients)) as cols
    from foodstuff
) t
pivot (
    max(ingredients) for cols in ([ingredient1],[ingredient2],[ingredient3]) 
) as p

输出:

food        ingredient1  ingredient2    ingredient3
sandwich    Bread        Butter         Jam

答案 2 :(得分:0)

这使用注入编码(请阅读安全风险潜力)。 还要归功于@jpw,因为我过去常常根据代码提供答案。 该代码允许增加或减少成分的数量,并将进行调整。

DECLARE @col AS NVARCHAR(MAX);
DECLARE @query AS NVARCHAR(MAX);
select @col = STUFF((SELECT distinct ',' +
                    QUOTENAME('ingredients'+cast(row_number () over (partition by food order by ingredients) as varchar (max)))
                  FROM ##t1
                  FOR XML PATH(''), TYPE
                 ).value('.', 'NVARCHAR(MAX)') 
                    , 1, 1, '')
 ;
 select @query =
 '
 select food, ' + @col + '
   from (
         select 
           food,
           ingredients, 
           ''ingredients''+ cast(row_number() over (partition by food order by ingredients)as varchar (10)) as cols
         from foodstuff
         ) t
 pivot (
        max(ingredients) for cols in (' + @col + ') 
        ) as p
 ;'
 ;
execute(@query);