我如何为人群建模?

时间:2015-06-04 17:55:27

标签: database database-design data-modeling

我需要为人群建模,我无法找到设计表格的方法来有效地进行。

可以将组视为一组,一个或多个人的无序集合,每个组应由其组件唯一标识。

编辑:一个人可以成为多个小组的成员。

我的第一次尝试看起来像这样。 包含所有"人员的表格#34;由系统管理。

table Persons(
  id int,
  name varchar,
  (other data...)
)

包含组和所有组属性的表:

table Groups(
  group_id int,
  group_name varchar,
  (other data...)
)

以及包含人与群体之间关联的表格

table gropus_persons (
  person_id int,
  group_id in
)

此设计不符合此要求,因为很难编写查询以从组件列表中检索组ID。

我唯一可以找到由人(1,2,3)组成的小组的查询如下:

select *
from groups g
where 
  g.group_id in (select group_id from gropus_persons where person_id = 1) 
  and g.group_id in (select group_id from gropus_persons where person_id = 2) 
  and g.group_id in (select group_id from gropus_persons where person_id = 3)
  and not exists (select 1 from gropus_persons where group_id = g.group_id and person_id not in (1,2,3))

问题是组件的数量是可变的,因此我只能使用动态生成的查询,并在每次需要查找新组时为每个组件添加子查询。

有更好的解决方案吗?

感谢您的帮助建议!

2 个答案:

答案 0 :(得分:0)

您需要按"组"进行分组。并计算您收到的点击次数。为此,您只需要交集表:

select GroupID, count(*) as MemberCount
from   GroupsPersons
where  PersonID in( 1, 2, 3 )
group by GroupID
having count(*) = 3;

问题在于使此查询适用于不同的人员ID值列表。你似乎已经意识到这需要动态SQL,伪代码看起来像这样:

stmt := 'select GroupID, count(*) as MemberCount '
     || 'from   GroupsPersons '
     || 'where  PersonID in( ' || CSVList || ' ) '
     || 'group by GroupID '
     || 'having count(*) = ' || length( CSVList );

您必须警惕的一个潜在错误是,如果列表中重复相同的ID。例如:CSVList := '1, 2, 3, 2';

这将生成正确的count(*)值3,但having子句将查找4。

答案 1 :(得分:0)

要考虑的另一个解决方案是以alpha序列旋转/ xpath人员ID集并将其存储在您的groups表中,并将该字符串与您的目标进行比较。

对于您的示例,您使用Select group_id from groups where personIDs = '1,2,3,'