如何在不使用 JOIN 的情况下解决 SQL 中的问题?
How can I solve my question in SQL without using a JOIN?
Data : Desired result:
class type number class rate score
------------------------- ----------------------
2021 1 5 2021 0.5 4.8
2021 1 4.6 2022 0.5 4.6
2021 0 4.8
2021 null null
2022 1 4.2
2022 1 5
2022 0 4.2
2022 null null
- rate = (type = 1 / all list) group by class.
- score = AVG(number) where type = 1 group by class.
我想做如下:
SELECT
a.class, SUM(type) / COUNT(*) AS rate, b.score
FROM
data as a
LEFT JOIN
(SELECT
class, AVG(number) AS score
FROM
data
WHERE
type = 1
GROUP BY
class) AS b ON a.class = b.class
GROUP BY
class
有没有不用 JOIN 的方法?
首先应该命名一些问题:
- 不要使用 SQL 类型或数字等关键字作为列名称或 table 名称。
- 如果不排除可能被零除的例外情况,请勿进行除法。
无论如何,如果您的描述是正确的,您可以进行以下操作:
SELECT class,
ROUND(AVG(CAST(COALESCE(type,0) AS FLOAT)),2) AS rate,
ROUND(AVG(CASE WHEN type = 1 THEN COALESCE(number,0) END),2) AS score
FROM data
GROUP BY class;
你可以在这里看到它工作正常:db<>fiddle
一些解释:
AVG
将在不进行有风险的除法的情况下建立平均值。
COALESCE
用零替换 NULL 值以确保平均值正确。
ROUND
确保平均值显示为 0.33,而不是 0.33333...
如果这对你来说还不够,请更准确地说明你到底想做什么。
Data : Desired result:
class type number class rate score
------------------------- ----------------------
2021 1 5 2021 0.5 4.8
2021 1 4.6 2022 0.5 4.6
2021 0 4.8
2021 null null
2022 1 4.2
2022 1 5
2022 0 4.2
2022 null null
- rate = (type = 1 / all list) group by class.
- score = AVG(number) where type = 1 group by class.
我想做如下:
SELECT
a.class, SUM(type) / COUNT(*) AS rate, b.score
FROM
data as a
LEFT JOIN
(SELECT
class, AVG(number) AS score
FROM
data
WHERE
type = 1
GROUP BY
class) AS b ON a.class = b.class
GROUP BY
class
有没有不用 JOIN 的方法?
首先应该命名一些问题:
- 不要使用 SQL 类型或数字等关键字作为列名称或 table 名称。
- 如果不排除可能被零除的例外情况,请勿进行除法。
无论如何,如果您的描述是正确的,您可以进行以下操作:
SELECT class,
ROUND(AVG(CAST(COALESCE(type,0) AS FLOAT)),2) AS rate,
ROUND(AVG(CASE WHEN type = 1 THEN COALESCE(number,0) END),2) AS score
FROM data
GROUP BY class;
你可以在这里看到它工作正常:db<>fiddle
一些解释:
AVG
将在不进行有风险的除法的情况下建立平均值。COALESCE
用零替换 NULL 值以确保平均值正确。ROUND
确保平均值显示为 0.33,而不是 0.33333...
如果这对你来说还不够,请更准确地说明你到底想做什么。