Mysql 从与第三个表相关的两个表中获取计算

Mysql 从与第三个表相关的两个表中获取计算,mysql,left-join,inner-join,Mysql,Left Join,Inner Join,我有这张桌子 table1 | id | name | | 1 | axe | | 2 | bow | | 3 | car | | 4 | dart | 这两张桌子呢 table2 table3 | t1_id | number | | t1_id | letter | |

我有这张桌子

     table1
|  id  |  name  |
|  1   |  axe   |
|  2   |  bow   |
|  3   |  car   |
|  4   |  dart  |
这两张桌子呢

        table2                                        table3
|  t1_id  |  number  |                        |  t1_id  |  letter  |
|  1      |  5       |                        |  1      |  a       |
|  1      |  6       |                        |  1      |  b       |
|  1      |  2       |                        |  1      |  c       |
|  2      |  2       |                        |  2      |  a       |
|  2      |  2       |                        |  2      |  c       |
|  2      |  3       |                        |  2      |  r       |
|  3      |  8       |                        |  3      |  y       |
|  3      |  3       |                        |  3      |  i       |
|  3      |  1       |                        |  3      |  a       |
|  4      |  8       |                        |  4      |  a       |
|  4      |  9       |                        |  4      |  b       |
|  4      |  10      |                        |  4      |  c       |
其中t1_id表1 id

我想做的是得到所有表1记录,这些记录包含表3字母a b c和它们的数字的平均值,顺序如下:按字母计数然后按平均值DESC

|  id  |  name  |  letter_count  |  avg_number   |
|  4   |  dart  |  3             |  9            |
|  1   |  axe   |  3             |  4.3333333333 |
|  2   |  bow   |  2             |  2.3333333333 |
|  3   |  car   |  1             |  4            |
我希望能够正常工作的查询是

但数字完全不同,而且准确,但顺序是正确的

我不想得到字母计数和平均数值,但我只想按它们排序,但它们的值让我担心查询性能

我不会注意到这些奇怪的值,因为我的实际查询是

SELECT 
  t1.id, 
  t1.name

FROM 
  table1 t1

INNER JOIN 
  table2 t2
    ON t2.t1_id = t1.id

LEFT JOIN 
  table3 t3
    ON t3.t1_id = t1.id
      AND t3.letter IN ('a', 'b', 'c')

GROUP BY
  t1.id

ORDER BY
  COUNT(t3.letter) DESC,
  AVG(t2.number) DESC
这只会给我适当的秩序

|  id  |  name  |
|  4   |  dart  |
|  1   |  axe   |
|  2   |  bow   |
|  3   |  car   |

但是在检查了这些值之后,我被字母计数所超过了,我是否忽略了这些值,而这不会影响我的大表中的性能呢?

您在两个不同的维度上进行聚合。这就产生了笛卡尔积。解决此问题的一种方法是在加入之前进行聚合:


在第三个表中,选择IN-SELECT子查询


SELECT 
  t1.id, 
  t1.name, 
  (
    SELECT count(letter)
    FROM  t3 
      where  t3.t1_id = t1.id
    ) as lettercount,
  AVG(t2.number) AS avg_number

FROM 
  table1 t1

INNER JOIN 
  table2 t2
    ON t2.t1_id = t1.id

如果我不需要
字母\u计数
数字\u平均值
,是否可以使用我的查询,在这种情况下会更快?它的执行计划似乎比我不理解的派生表更好,它的行数是这里的两倍
SELECT t1.id, t1.name, t2.letter_count, t2.avg_number
FROM table1 t1 INNER JOIN 
     (SELECT t2.t1_id, AVG(t2.number) as avg_number
      FROM table2 t2
      GROUP BY t2.t1_id
     ) t2
     ON t2.t1_id = t1.id LEFT JOIN
     (SELECT t3.t2_id, COUNT(t3.letter) as letter_count
      FROM table3 t3
      WHERE t3.letter IN ('a', 'b', 'c')
      GROUP BY t3.t2_id
     ) t3
     ON t3.t1_id = t1.id
ORDER BY t3.letter_count DESC, t2.avg_number DESC;

SELECT 
  t1.id, 
  t1.name, 
  (
    SELECT count(letter)
    FROM  t3 
      where  t3.t1_id = t1.id
    ) as lettercount,
  AVG(t2.number) AS avg_number

FROM 
  table1 t1

INNER JOIN 
  table2 t2
    ON t2.t1_id = t1.id