三个表的关系顺序是正确的,但值是错误的
three tables relation order is correct but values are false
我有那些表
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 |
and table1(id) 与 table2(t1_id), table3(t1_id)
i 运行 它让他们按 最高 letter_count 匹配然后按 最高 average_number 匹配以获得此 正确 结果 http://www.sqlfiddle.com/#!9/69086b/8/0
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 和 avg_number 所以我使用了这个查询
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
我期望的结果是
| 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
| id | name | letter_count | avg_number |
| 4 | dart | 9 | 9 |
| 1 | axe | 9 | 4.3333333333 |
| 2 | bow | 6 | 2.3333333333 |
| 3 | car | 3 | 4 |
令我惊讶的是 letter_count 的乘积行,可以通过 派生查询 解决,但我不知道想要 select letter_count 或 number_average 我只想 ORDER BY 他们
保持查询与使用 ORDER BY 一样只会影响查询性能,或者我是否仍应使用派生查询,即使我不需要 select 数据值,因为无论如何顺序都是正确的,或者派生查询在大表中会更快吗?
这将检索您需要的内容:
SELECT a.id, a.name, count(a.letter) letter_count, avg(a.number) avg_number
FROM( SELECT
t1.id,
t1.name,
t3.letter,
t2.number--,
FROM
table1 t1
INNER JOIN
table2 t2
ON t2.t1_id = t1.id
INNER JOIN
table3 t3
ON t3.t1_id = t1.id
AND t3.letter IN ('a', 'b', 'c')
GROUP BY
t1.id, t1.name, t3.letter, t2.number) a GROUP BY id, a.name
ORDER BY
letter_count DESC,
avg_number DESC
你在这里真的问了 2 个问题:
ORDER BY
子句是否影响查询性能
- 为什么我的信数不符合预期
无论哪种方式,要计算 ORDER BY
子句,都需要计算表达式以便确定顺序。在您的第一个示例中,您需要指定表达式,因为这些列未包含在 SELECT
语句中。
但是在你的第二个查询中你选择了你想要排序的列,因为 ORDER BY
被计算 AFTER 整个查询已经被处理,你可以只需在 ORDER BY
子句中使用列 ALIAS,而不是再次执行函数。
some RDBMS query optimisers will convert your expressions in the ORDER BY
statements to use the column alias for you IF you are ordering on expressions that exist in your SELECT
clause
你这样做是对的,但是,由于响应中的重复项,你的字母计数表达式不是最新的。
您可以简单地更改 COUNT
表达式以使用不同的子句来仅计算唯一值。
COUNT(DICTINCT t3.letter)
这使您的原始查询现在看起来像这样:
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(DICTINCT t3.letter) DESC,
AVG(t2.number) DESC
我有那些表
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 |
and table1(id) 与 table2(t1_id), table3(t1_id)
i 运行 它让他们按 最高 letter_count 匹配然后按 最高 average_number 匹配以获得此 正确 结果 http://www.sqlfiddle.com/#!9/69086b/8/0
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 和 avg_number 所以我使用了这个查询
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
我期望的结果是
| 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
| id | name | letter_count | avg_number |
| 4 | dart | 9 | 9 |
| 1 | axe | 9 | 4.3333333333 |
| 2 | bow | 6 | 2.3333333333 |
| 3 | car | 3 | 4 |
令我惊讶的是 letter_count 的乘积行,可以通过 派生查询 解决,但我不知道想要 select letter_count 或 number_average 我只想 ORDER BY 他们
保持查询与使用 ORDER BY 一样只会影响查询性能,或者我是否仍应使用派生查询,即使我不需要 select 数据值,因为无论如何顺序都是正确的,或者派生查询在大表中会更快吗?
这将检索您需要的内容:
SELECT a.id, a.name, count(a.letter) letter_count, avg(a.number) avg_number
FROM( SELECT
t1.id,
t1.name,
t3.letter,
t2.number--,
FROM
table1 t1
INNER JOIN
table2 t2
ON t2.t1_id = t1.id
INNER JOIN
table3 t3
ON t3.t1_id = t1.id
AND t3.letter IN ('a', 'b', 'c')
GROUP BY
t1.id, t1.name, t3.letter, t2.number) a GROUP BY id, a.name
ORDER BY
letter_count DESC,
avg_number DESC
你在这里真的问了 2 个问题:
ORDER BY
子句是否影响查询性能- 为什么我的信数不符合预期
无论哪种方式,要计算 ORDER BY
子句,都需要计算表达式以便确定顺序。在您的第一个示例中,您需要指定表达式,因为这些列未包含在 SELECT
语句中。
但是在你的第二个查询中你选择了你想要排序的列,因为 ORDER BY
被计算 AFTER 整个查询已经被处理,你可以只需在 ORDER BY
子句中使用列 ALIAS,而不是再次执行函数。
some RDBMS query optimisers will convert your expressions in the
ORDER BY
statements to use the column alias for you IF you are ordering on expressions that exist in yourSELECT
clause
你这样做是对的,但是,由于响应中的重复项,你的字母计数表达式不是最新的。
您可以简单地更改 COUNT
表达式以使用不同的子句来仅计算唯一值。
COUNT(DICTINCT t3.letter)
这使您的原始查询现在看起来像这样:
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(DICTINCT t3.letter) DESC,
AVG(t2.number) DESC