SQL使用一个表中的列值作为另一个表的列来获取数据

时间:2018-02-01 10:24:34

标签: sql oracle

我有这两个表:

Org_Extra_Attr

org_id      attr_name       attr_path
1           desk_name       str1
1           citizen         bool1           
2           perm_user       bool1           
3           skype_id        str1            
3           twitter         str2

User_Attr_Values

org_id      user_id     str1    str2    str3    str4    bool1   bool2   bool3   bool4
1           1           b1d07   null    null    null    1       null    null    null
1           2           b2d01   null    null    null    0       null    null    null
2           3           null    null    null    null    1       null    null    null
2           4           null    null    null    null    1       null    null    null
3           5           sam_sky sam_twt null    null    null    null    null    null
3           6           tom_sky tom_twt null    null    null    null    null    null

所以,这里的每一个org.can都定义了最多4个类型为String和Boolean的额外属性,Org_Extra_Attr表就像元数据。例如,org_id 1定义了desk_name,它将是str1的用户值,而org_id 3的skype_id将是str1的用户值。

这可能是一个糟糕的设计,但是现在,我需要获取给定org_id的用户属性名称和值。就像org_id = 1一样,我需要一个SQL查询结果(不是第三个表),如下所示:

user_id     attr_name   val
1           desk_name   b1d07
1           citizen     1
2           desk_name   b2d01
2           citizen     0

对于org_id = 3

user_id     attr_name   val
5           skype_id    sam_sky
5           twitter     sam_twt
6           skype_id    tom_sky
6           twitter     tom_twt

2 个答案:

答案 0 :(得分:1)

像这样的东西

select 
t2.user_id,
t1.attr_name,
    CASE
    WHEN t1.attr_path='str1' then t2.str1
    WHEN t1.attr_path='str2' then t2.str2
    WHEN t1.attr_path='str3' then t2.str3
    WHEN t1.attr_path='str4' then t2.str4
    WHEN t1.attr_path='bool1' then t2.bool1
    WHEN t1.attr_path='bool2' then t2.bool2
    WHEN t1.attr_path='bool3' then t2.bool3
    WHEN t1.attr_path='bool4' then t2.bool4
END attr_value
FROM org_Extra_attr t1 inner join User_Attr_Values t2
on t1.org_id = t2.org_id
where t1.org_id=1

答案 1 :(得分:0)

这不是答案,但评论时间太长

这是一个糟糕的数据模型。您不应在表中存储列名称。

你可以拥有的是:

Org_Attr (PK = org_id + attr_no)

org_id   attr_no   attr_name   type
1        1         desk_name   STRING
1        2         citizen     BOOL
2        1         perm_user   BOOL
3        1         skype_id    STRING
3        2         twitter     STRING

Org_Attr_User (PK = org_id + attr_no + user_id)

org_id   attr_no   user_id   value
1        1         1         b1d07   
1        1         2         b2d01   
1        2         1         1
1        2         2         0
2        1         3         1
2        1         4         1
3        1         5         sam_sky    
3        1         6         tom_sky   
3        2         5         sam_twt   
3        2         6         tom_twt

使用这样的模型可以保证数据的完整性,并且查询也很简单:

select oau.user_id, oa.attr_name, oau.value
from Org_Attr oa
join Org_Attr_User oau using (org_id, attr_no)
where org_id = 1;