Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
多个表中匹配记录的MySQL计数_Mysql_Sql_Select - Fatal编程技术网

多个表中匹配记录的MySQL计数

多个表中匹配记录的MySQL计数,mysql,sql,select,Mysql,Sql,Select,考虑到以下4个表: entity table1 table2 table3 ------ ------------- ------------- ------------- id ei(entity.id) ei(entity.id) ei(entity.id) name something somethingelse yetanother 如何计算所有三个表中的实体用法,如 --------------------- |

考虑到以下4个表:

entity  table1        table2        table3       
------  ------------- ------------- -------------
id      ei(entity.id) ei(entity.id) ei(entity.id)
name    something     somethingelse yetanother
如何计算所有三个表中的实体用法,如

---------------------
| id | t1 | t2 | t3 |
---------------------
|  1 | 14 | 23 |  0 |
|  2 | 66 |  9 |  5 |
...
我最初的方法是从实体中选择,然后左键连接其他表,但MySQL似乎不喜欢它

SELECT e.id,count(t1.id) FROM entity AS e LEFT JOIN table1 AS t1 on e.id=t1.ei;
编辑:这是1表的输出

mysql> explain select e.id,count(o.id) from entity e left join table1 t1 on e.id=o.ei where e.ty=3; +----+-------------+-------+------+---------------+------+---------+------+-------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+-------+-------------+ | 1 | SIMPLE | e | ALL | NULL | NULL | NULL | NULL | 1083 | Using where | | 1 | SIMPLE | o | ALL | NULL | NULL | NULL | NULL | 90201 | | +----+-------------+-------+------+---------------+------+---------+------+-------+-------------+ 2 rows in set (0.04 sec) ==


重写此查询的另一种方法

在每个表中分别分组和计数,然后加入:

SELECT  a.id, 
        COALESCE(b.t1, 0) AS t1,
        COALESCE(c.t2, 0) AS t2,
        COALESCE(d.t3, 0) AS t3
FROM
        entity a
    LEFT JOIN
        ( SELECT ei,
                 COUNT(*) AS t1
          FROM table1
          GROUP BY ei
        ) AS b
            ON a.id = b.ei
    LEFT JOIN
        ( SELECT ei,
                 COUNT(*) AS t2
          FROM table2
          GROUP BY ei
        ) AS c
            ON a.id = c.ei
    LEFT JOIN
        ( SELECT ei,
                 COUNT(*) AS t3
          FROM table3
          GROUP BY ei
        ) AS d
            ON a.id = d.ei
  ;


如果没有索引的话,您肯定应该在3个表的
(ei)
上添加一个索引。

我尝试过并不得不在大约一分钟后终止查询,而单独运行计数需要0.04秒。。。我预计需要0.12s(?)这列上有索引吗<代码>实体.id,
表1.ei
表2.ei
表3.ei
?您能将结果发布到这里吗?@单线程问题是您没有在链接列上添加索引,请尝试使用此
ALTER table table 1 add index t1_idx(ei)
,以及其他表来更改表。然后重试该查询。
entity.id
是主键吗?不幸的是,这不是一个选项。我感到惊讶的是,每个人的计数都非常快。通过e.id整合3个结果不会花那么长时间!为什么改变不是一种选择?您可以添加
解释
哪个查询连接了三个表吗?请这是因为列上没有
索引。在解释结果中查看
可能的\u键的值。这也会产生一个很长的查询(几分钟后)哇。创造奇迹。您可能需要在每个from之前修复额外的“,”,顺便说一句,如果没有索引,查询需要0.5秒,这对我来说非常合适。如果您喜欢0.5而不是0.005,我也可以。我不明白为什么人们不想在他们的表中放置索引,这就是他们的目的,以提高效率。这个特殊的请求是由手动用户干预触发的。因此,低于1s的一切都是可以接受的。我担心额外的索引会减慢批量插入并增加总体大小,这更令人担忧。
entity.id
似乎是主键,
tableX.ei
似乎是外键。一般来说,这些应该被编入索引,因为连接经常会用到它们。由于当前磁盘空间如此便宜,为什么总体大小会成为一个问题?这是在有限的设备上运行的吗?
SELECT  a.ID, 
        COUNT(b.ei) t1,
        COUNT(c.ei) t2,
        COUNT(d.ei) t3
FROM    entity a
        LEFT JOIN table1 b
            ON a.id = b.ei
        LEFT JOIN table2 c
            ON a.id = c.ei
        LEFT JOIN table3 d
            ON a.ID = d.ei
GROUP BY a.ID
select select 
e.id,
sum(case when t1.name is null then 0 else 1 end) t1,
sum(case when t2.name is null then 0 else 1 end) t2,
sum(case when t3.name is null then 0 else 1 end) t3
from
entity e left join table1 t1 on e.id=t1.ei left join table2 t2 on e.id=t2.ei left join table3 t3 on e.id=t3.ei
group by e.id
SELECT  a.id, 
        COALESCE(b.t1, 0) AS t1,
        COALESCE(c.t2, 0) AS t2,
        COALESCE(d.t3, 0) AS t3
FROM
        entity a
    LEFT JOIN
        ( SELECT ei,
                 COUNT(*) AS t1
          FROM table1
          GROUP BY ei
        ) AS b
            ON a.id = b.ei
    LEFT JOIN
        ( SELECT ei,
                 COUNT(*) AS t2
          FROM table2
          GROUP BY ei
        ) AS c
            ON a.id = c.ei
    LEFT JOIN
        ( SELECT ei,
                 COUNT(*) AS t3
          FROM table3
          GROUP BY ei
        ) AS d
            ON a.id = d.ei
  ;