我写了一个查询,其中有一个包含人名的文件。每个人都有一个家庭ID。因此,同一家庭的多个成员都将具有相同的ID。
我编写了一个查询,首先列出家庭ID,然后列出同一输出行上的所有家庭成员。
即
ID39874约翰史密斯哈里史密斯简史密斯我有一些超过9个家庭成员的家庭。我的以下查询在测试具有少量记录的小文件时非常有用。但是,当我使用超过20,000条记录的文件运行查询时,我的系统挂起了很多。我知道我的系统因为有太多的子查询而被杀死了,但是为了进行测试,我无法找到任何其他方法来解决这个问题。
任何人都可以提出另一种方法来解决这个问题而不会破坏我的系统。感谢
注意 - 我知道我有8个子查询,涵盖最多9个家庭成员的家庭。任何少于9个成员的家庭只会将成员输出为空值,所以我对这个结果没问题。
select v.family_id, v.full_name,
(select b.full_name
from family_table b
where v.family_id = b.family_id
LIMIT 1,1) as voter_02,
(select c.full_name
from family_table c
where v.family_id = c.family_id
LIMIT 2,1) as voter_03,
(select d.full_name
from family_table d
where v.family_id = d.family_id
LIMIT 3,1) as voter_04,
(select e.full_name
from family_table e
where v.family_id = e.family_id
LIMIT 4,1) as voter_05,
(select f.full_name
from family_table f
where v.family_id = f.family_id
LIMIT 5,1) as voter_06,
(select g.full_name
from family_table g
where v.family_id = g.family_id
LIMIT 6,1) as voter_07,
(select h.full_name
from family_table h
where v.family_id = h.family_id
LIMIT 7,1) as voter_08,
(select i.full_name
from family_table i
where v.family_id = i.family_id
LIMIT 8,1) as voter_09
from family_table v
group by family_id
答案 0 :(得分:2)
如果一个家庭有> 8个人?我认为您使用的子查询方法不是一种可扩展的方法来获取所有家庭成员。
话虽如此,我认为你在这里有两个选择:
选项1(GROUP_CONCAT):
SELECT v.family_id, GROUP_CONCAT(v.fullname) as voters
FROM family_table v
GROUP BY v.family_id
这里有一个SQLFiddle来显示结果集:http://sqlfiddle.com/#!9/6da73/1
选项2(将所有选民作为单独的行返回,彼此相邻):
SELECT v.family_id, v.fullname
FROM family_table v
ORDER BY v.family_id:
选项3(不是我最喜欢的,可以做得更好,但我相信它应该比你正在使用的子查询更快):
SELECT v.family_id, v.fullname, v2.fullname, v3.fullname, v4.fullname, v5.fullname,
v6.fullname, v7.fullname, v8.fullname
FROM family_table v
LEFT JOIN family_table v2 ON v2.family_id = v.family_id AND v2.fullname != v.fullname
LEFT JOIN family_table v3 ON v3.family_id = v.family_id AND v3.fullname NOT IN (v.fullname, v2.fullname)
LEFT JOIN family_table v4 ON v4.family_id = v.family_id AND v4.fullname NOT IN (v.fullname, v2.fullname, v3.fullname)
LEFT JOIN family_table v5 ON v5.family_id = v.family_id AND v5.fullname NOT IN (v.fullname, v2.fullname, v3.fullname, v4.fullname)
LEFT JOIN family_table v6 ON v6.family_id = v.family_id AND v6.fullname NOT IN (v.fullname, v2.fullname, v3.fullname, v4.fullname,
v5.fullname)
LEFT JOIN family_table v7 ON v7.family_id = v.family_id AND v7.fullname NOT IN (v.fullname, v2.fullname, v3.fullname, v4.fullname,
v5.fullname, v6.fullname)
LEFT JOIN family_table v8 ON v8.family_id = v.family_id AND v8.fullname NOT IN (v.fullname, v2.fullname, v3.fullname, v4.fullname,
v5.fullname, v6.fullname, v7.fullname)
LEFT JOIN family_table v9 ON v9.family_id = v.family_id AND v9.fullname NOT IN (v.fullname, v2.fullname, v3.fullname, v4.fullname,
v5.fullname, v6.fullname, v7.fullname, v8.fullname)
GROUP BY v.family_id;
注意:对于NOT IN部分,如果每行都有一个主键,则应该使用该主键作为not key,因为它将被更好地编入索引(并且有2个人很少)在1个家庭中有相同的名称)
答案 1 :(得分:0)
索引“family_id”列使我的原始查询快速运行。谢谢@blackpen的评论。
我希望在某个时候,想要找出一个可以覆盖任意数量的家庭成员的查询,而不仅仅是我硬编码的大量子查询。但这绝对适用于现在。感谢@Pachonk的输入。