2010-11-05 110 views
0

我的「人員」表每個人都有一行,並且該人擁有一個部門(不是唯一的)和一個公司(不是唯一的)。SQL將多個記錄合併爲一個默認值

我需要加入的人p_features,c_features,d_features上:

people.person=p_features.num_value 
people.division=d_features.num_value 
people.company=c_features.num_value 

...的方式,如果有一個創紀錄的比賽中p_features/d_features/c_features而已,它會被退回,但如果它在2或3個表格中,則會返回最具體的記錄。

從下面我的測試數據,例如,查詢人= 1將返回 「FALSE」
人3倍的回報或許,人4個返回true,和人9返回默認

最大的問題是,有100個功能,我有查詢需要將它們全部返回一行。我以前的嘗試是一個函數,它查詢每個表中的特性num_value,並做了一個foreach,但100個特性* 4表意味着400次讀取,並且它導致數據庫停止運行,當我載入幾百萬行數據。

create table p_features (
     num_value int8, 
     feature varchar(20), 
     feature_value varchar(128) 
); 
create table c_features (
     num_value int8, 
     feature varchar(20), 
     feature_value varchar(128) 
); 
create table d_features (
     num_value int8, 
     feature varchar(20), 
     feature_value varchar(128) 
); 
create table default_features (
     feature varchar(20), 
     feature_value varchar(128) 
); 
create table people (
     person int8 not null, 
     division int8 not null, 
     company int8 not null 
); 
insert into people values (4,5,6); 
insert into people values (3,5,6); 
insert into people values (1,2,6); 
insert into p_features values (4,'WEARING PANTS','TRUE'); 
insert into c_features values (6,'WEARING PANTS','FALSE'); 
insert into d_features values (5,'WEARING PANTS','MAYBE'); 
insert into default_features values('WEARING PANTS','DEFAULT'); 

回答

0

您需要將特徵轉置爲具有排名的行。在這裏我使用了一個通用表格表達式。如果您的數據庫產品不支持它們,您可以使用臨時表達到相同的效果。

;With RankedFeatures As 
    (
    Select 1 As FeatureRank, P.person, PF.feature, PF.feature_value 
    From people As P 
     Join p_features As PF 
      On PF.num_value = P.person 
    Union All 
    Select 2, P.person, PF.feature, PF.feature_value 
    From people As P 
     Join d_features As PF 
      On PF.num_value = P.division 
    Union All 
    Select 3, P.person, PF.feature, PF.feature_value 
    From people As P 
     Join c_features As PF 
      On PF.num_value = P.company 
    Union All 
    Select 4, P.person, DF.feature, DF.feature_value 
    From people As P 
     Cross Join default_features As DF 
    ) 
    , HighestRankedFeature As 
    (
    Select Min(FeatureRank) As FeatureRank, person 
    From RankedFeatures 
    Group By person 
    ) 
Select RF.person, RF.FeatureRank, RF.feature, RF.feature_value 
From people As P 
    Join HighestRankedFeature As HRF 
     On HRF.person = P.person 
    Join RankedFeatures As RF 
     On RF.FeatureRank = HRF.FeatureRank 
      And RF.person = P.person 
Order By P.person 
+0

這太棒了。我在Informix中沒有公共表格,因此我爲RankingFeatures提供了一個視圖,並且所有工作都完美無缺。非常感謝你的努力! – user490231 2010-11-05 17:24:55

+0

還有一件事,因爲如果我有5個特徵,我有5行,我可以將其視爲水平視圖,例如: 選擇人,(特徵值='穿着褲子'時的值), feature ='WEARING HAT')等從你的桌子上面..希望是有道理的。 – user490231 2010-11-05 17:27:43

0

我不知道,如果我非常理解你的問題,但使用JOIN,你需要你的表已經加載,然後使用選擇語句INNER JOIN,LEFT JOIN或什麼你需要展示。 如果你發佈一些更多的信息,也許變得很容易理解。

0

我不理解你的模式的某些方面,比如如果在任何特定表中沒有匹配,如何與default_features表相關聯。唯一可能的加入條件是feature,但如果其他3個表中沒有匹配,則沒有值加入。因此,在我的例子中,我對DEFAULT進行了硬編碼,因爲我想不出如何得到它。

希望這可以讓你開始,如果你可以澄清模型多一點,解決方案可以改進。

select p.person, coalesce(pf.feature_value, df.feature_value, cf.feature_value, 'DEFAULT') 
    from people p 
     left join p_features pf 
      on p.person = pf.num_value 
     left join d_features df 
      on p.division = df.num_value 
     left join c_features cf 
      on p.company = cf.num_value