SQL将多个记录连接到一个具有默认值的记录

时间:2010-11-05 15:34:11

标签: 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个表中,则返回最具体的记录。

从下面的测试数据中,例如,对person = 1的查询将返回 “假”
 人3可能返回,人4返回true,而人9返回默认

最大的问题是有100个功能,我有查询需要在一行中返回所有这些功能。我以前的尝试是一个函数,它查询每个表中的feature,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');

3 个答案:

答案 0 :(得分:0)

我不知道我是否理解你的问题,但是要使用JOIN,你需要加载你的表,然后使用 SELECT 语句 INNER JOIN,LEFT JOIN 或者您需要展示的任何内容。 如果您发布更多信息,可能会更容易理解。

答案 1 :(得分: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

答案 2 :(得分: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