我需要为人群建模,我无法找到设计表格的方法来有效地进行。
可以将组视为一组,一个或多个人的无序集合,每个组应由其组件唯一标识。
编辑:一个人可以成为多个小组的成员。
我的第一次尝试看起来像这样。 包含所有"人员的表格#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))
问题是组件的数量是可变的,因此我只能使用动态生成的查询,并在每次需要查找新组时为每个组件添加子查询。
有更好的解决方案吗?
感谢您的帮助建议!
答案 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,'