SQL 将 MAX 应用于具有非空行的左联接 table
SQL apply MAX to left join table having non null rows
table 姓名:国家
id country_name
1 USA
2 GERMANY
3 RUSSIA
table 姓名:用户
id user_name points country_id
1 user1 20 1
2 user2 10 2
3 user3 11 2
结果应该是最高分的国家/地区用户,如果没有可用的用户(第 3 条记录),则只有国家/地区,如下所示
country_name user_name points
USA user1 20
GERMANY user3 11
RUSSIA (null) (null)
目前我正在使用以下查询,但有时会花费太多时间,比如当我有 100000 条记录时。
SELECT c.country_name,u.user_name,u.points FROM country c
LEFT JOIN user u on u.country_id = c.id
WHERE (u.points = (SELECT MAX(points) AS points FROM user WHERE user.id = u.id) OR u.points IS NULL)
那么,有没有其他方法可以更有效地节省时间。
已经谢谢了!
您可以使用 ROW_NUMBER()
:
SELECT c.country_name, u.user_name, u.points
FROM country c LEFT JOIN
(SELECT u.*,
ROW_NUMBER() OVER (PARTITION BY u.country_id ORDER BY u.points DESC) as seqnum
FROM user u
WHERE u.points IS NOT NULL
) u
ON u.country_id = c.id AND u.seqnum = 1;
注意:此 returns 每个国家/地区一个用户,即使排名靠前的用户并列。如果您想要所有这些,请使用 RANK()
而不是 ROW_NUMBER()
。
table 姓名:国家
id country_name
1 USA
2 GERMANY
3 RUSSIA
table 姓名:用户
id user_name points country_id
1 user1 20 1
2 user2 10 2
3 user3 11 2
结果应该是最高分的国家/地区用户,如果没有可用的用户(第 3 条记录),则只有国家/地区,如下所示
country_name user_name points
USA user1 20
GERMANY user3 11
RUSSIA (null) (null)
目前我正在使用以下查询,但有时会花费太多时间,比如当我有 100000 条记录时。
SELECT c.country_name,u.user_name,u.points FROM country c
LEFT JOIN user u on u.country_id = c.id
WHERE (u.points = (SELECT MAX(points) AS points FROM user WHERE user.id = u.id) OR u.points IS NULL)
那么,有没有其他方法可以更有效地节省时间。
已经谢谢了!
您可以使用 ROW_NUMBER()
:
SELECT c.country_name, u.user_name, u.points
FROM country c LEFT JOIN
(SELECT u.*,
ROW_NUMBER() OVER (PARTITION BY u.country_id ORDER BY u.points DESC) as seqnum
FROM user u
WHERE u.points IS NOT NULL
) u
ON u.country_id = c.id AND u.seqnum = 1;
注意:此 returns 每个国家/地区一个用户,即使排名靠前的用户并列。如果您想要所有这些,请使用 RANK()
而不是 ROW_NUMBER()
。