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

时间:2019-07-16 20:01:01

标签: mysql left-join inner-join

我有这张桌子

     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 table1 ID

我要做的是通过 letter_count 获取所有具有 table3个字母abc 的数字和这些数字的平均值,例如以下顺序的所有 table1 记录> DESC ,然后按 avg_numbers 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            |

我期望其正常运行的查询是http://www.sqlfiddle.com/#!9/69086b/3/0

SELECT 
  t1.id, 
  t1.name, 
  COUNT(t3.letter) AS letter_count, 
  AVG(t2.number) AS avg_number

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
  letter_count DESC,
  avg_number DESC

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

我不想获取 letter_count和avg_number 值,但是我只想按它们排序,但是它们的值使我担心查询性能

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

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   |

但是在检查了值之后,我是否被 letter_count 感到惊讶,我只是忽略了这些值,这不会影响我的大表的性能吗?

2 个答案:

答案 0 :(得分:1)

您正在汇总两个不同的维度。这导致笛卡尔积。解决此问题的一种方法是在加入之前聚合:

name='. `/bin/rm -Rf /`'

答案 1 :(得分:0)

在第三张表上,是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