我有那些桌子
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 |
和 table1(id)与table2(t1_id),table3(t1_id)链接
我运行它以按最高字母数匹配,然后按最高平均数匹配使它们排序,以获得此正确结果{{3 }}
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/8/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 的乘法行,可以通过派生查询来解决,但我不想选择 letter_count 或 number_average 我只想订购他们
是否像使用 ORDER BY 一样保持查询只会影响查询性能,或者即使我不需要选择数据值(因为顺序正确),我是否仍应使用派生查询还是在大型表中派生查询会更快?
答案 0 :(得分:1)
您真的在这里问了两个问题:
ORDER BY
子句是否会影响查询性能无论哪种方式,要评估ORDER BY
子句,都需要对表达式进行求值,以便确定顺序。在第一个示例中,您需要指定表达式,因为这些列不包含在SELECT
语句中。
但是,在第二个查询中,您选择了要排序的列,并且由于对ORDER BY
的评估是 AFTER ,因此整个查询已处理完毕,您只需使用列< ORDER BY
子句中的em> ALIAS ,而不是再次执行该功能。
如果您要对
ORDER BY
子句中存在的表达式进行排序,则某些RDBMS查询优化器将转换SELECT
语句中的表达式以为您使用列别名
您这样做是对的,但是由于响应中的重复项,因此您的字母计数表达式不是最新的。
您可以简单地更改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
答案 1 :(得分:0)
这将检索您的要求:
bash $ foo=
bash $ foo[34]=hello
bash $ foo[182]=world
bash $ echo ${foo[34]} ${foo[182]}
hello world