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

Sql 在保留父子关系的同时从数据中提取超集,sql,sql-server,tsql,database-design,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

我有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中是否有一个提取超级数据集的过程,同时仍然保留孩子(一个人)和父母(一顿饭)之间的关系?

如果您只想为每个唯一的菜创建一个唯一的编号,您可以使用行编号
(选择不同的菜)
。然后你只需使用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]

如果你想在同一时间对餐厅进行此操作,只需添加另一个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]


另外,如果将这些CTE放在表中,INSERT中的Output子句就是您的朋友。如果您只想为每个唯一的菜创建一个唯一的编号,您可以将行编号与
(选择不同的菜)
一起使用,则此过程称为规范化。然后你只需使用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]

如果你想在同一时间对餐厅进行此操作,只需添加另一个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]


另外,如果将这些CTE放在表中,INSERT中的Output子句就是您的朋友。这个过程被称为标准化

我认为以下方法可以做到这一点:

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。然后将它们连接回原始数据。

我认为以下方法可以做到这一点:

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。然后将它们连接回原始数据。

使用多个列是否有助于创建此代理“用餐”键?使用多个列是否有助于创建此代理“用餐”键?我喜欢
order by(选择NULL)
我喜欢
order by(选择NULL)