从数据中提取超集,同时保留父子关系

时间:2013-02-05 00:41:28

标签: sql sql-server tsql database-design

我在SQL中有数据,其粒度与以下类似。

Person ID    Dish        Restaurant              Cost 
1            Pasta       The Spaghetti House     5
2            Burgers     Burger Factory          7
3            Pasta       The Spaghetti House     5
4            Pizza       The Cheesy Slice        4

这只是一个例子,但它捕获了我的数据的本质,并提供了一个很好的例子。 我需要从这些数据中抽象出一顿“餐”(超级套餐),其中一顿饭包括一道菜,餐厅和成本。我需要生成一个独特的“餐”ID。需要注意的是,我需要将一个人与一顿饭联系起来。

PersonID    MealID        
1            1
2            2
3            1
4            3

到目前为止,我提出的最佳解决方案是从菜肴,餐厅和成本列中确定校验和。然后,我可以通过计算每行“校验和”来识别每个“用餐”,并让我通过计算每行的校验和将每个人与每个人联系起来。

我甚至不知道这个提取超级数据集的过程是什么,更不用说如何正确地完成它了。 (我挣扎着这个问题的标题)。我不确定使用校验和是最优雅的选择,虽然它似乎确实有用。

是否有一个提取超级数据集的过程,同时仍保留SQL中的孩子(一个人)和它的父母(一顿饭)之间的关系?

2 个答案:

答案 0 :(得分:2)

如果您只想为每个独特菜肴创建唯一编号,则可以将Row_Number与(select distinct dish)一起使用。然后你就可以用CTE加入这道菜了。

这可以保证人员ID 2和4将共享相同的MealID,但不保证订单。

;with d as (select row_number() over (order by dish) MealID,
        Dish 
        from
        (select distinct dish
        From Data) as t)
Select [person Id],
       MealID
from data
      inner join d
      on data.dish = d.dish
Order by [person id]

Demo

如果您想同时在餐厅同时添加另一个cte。

;with d as (select row_number() over (order by dish) MealID,
        Dish 
        from
        (select distinct dish
        From Data) as t)
, r as (select row_number() over (order by Restaurant) RestaurantID,
        Restaurant 
        from
        (select distinct Restaurant
        From Data) as t)

Select [person Id],
       MealID,
       RestaurantID
from data
      inner join d
      on data.dish = d.dish
      inner join r
      on data.restaurant = r.Restaurant
Order by [person id]

Demo

顺便说一句,如果你把这些ctes放在表中,INSERT中的Output子句就是你的朋友。此过程称为标准化

答案 1 :(得分:1)

我认为以下是这样的:

with mealids as (
    select t.*, row_number() over (order by (select NULL)) as mealid
    from (select distinct dish, restaurant, cost
          from t
         ) t
)
select t.personid, mealids.mealid 
from t join
     mealids
     on t.dish = mealids.dish and
        t.restaurant = mealids.restaurant and
        t.cost = mealids.cost

即,为数据中的组合生成id。然后将它们连接回原始数据。