mysql - 具有多个子查询的查询使我的系统挂起

标签 mysql subquery limit

我编写了一个查询,其中有一个包含人员姓名的文件。每个人都有一个家庭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

最佳答案

如果一个家庭有超过 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;

( SQL Fiddle )

注意:对于 NOT IN 部分,如果每行都有一个主键,则应该使用该主键作为 not in,因为它会更好地建立索引(并且有很小的机会 2 个人) 1个家庭有相同的名字)

关于mysql - 具有多个子查询的查询使我的系统挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39402305/

相关文章:

MySQL Subselect 将两个表和聚合函数合并到单个查询中

join - 如何使用 ElasticSearch 执行 "join"/"sub-query"?

php - 使用 LIKE 获得精确匹配 - SQL/PHP

mysql - SQL 每月将列中的所有值相加

mysql - mysql与node js连接后全局变量值显示未定义

MySQL Case 语句,在 'Statement List' 中返回多行(Then...之后的部分)

c - C语言中如何计算矩阵一行中元素的个数

mysql - 需要根据日期提取最后 x 行数

mysql - MySQL 限制器说明

mysql - 如何在 SQL 中设置记录相对于组的位置?