2013-02-05 50 views
0

我在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?

+0

將利用多個單列工作來創建此代用品「餐」密鑰? – Matt

回答

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

順便說一句,如果你把這些熱膨脹係數在表中插入輸出條款是你的朋友。這個過程被稱爲歸一化

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。然後將它們加回原始數據。

+0

我喜歡'order by(select NULL)' –

相關問題