如何在加入mysql后按组/类别获得前n个解决方案? [重复]

问题描述 投票:0回答:3

我正在加入2个表,然后希望每个组的前n个结果由第二个表中的列进行。我的mysql版本不允许我使用row_number()和WITH子句。

通过此查询,我可以加入我的城市和夜生活表:

SELECT cities.id, cities.city, cities.country, cities.region, nightlife.rating
JOIN nightlife ON nightlife.cityID = cities.id
WHERE cities.popular = true 
ORDER BY nightlife.rating DESC;

通过此查询,我可以按最高ID排序的每个地区获得2个城市:

SELECT id, city, country, region
FROM cities
WHERE cities.popular = true
AND
(
   SELECT count(*) FROM cities AS c
   WHERE c.region = cities.region AND c.id >= cities.id
) <= 2;

如何在一个查询中将它们组合在一起,获得具有最高夜生活等级的每个地区的前2个城市...而不使用row_number()和WITH子句?

预期结果

 id | city      | country | region | nightlife_rating
 ----------------------------------------------------
 1  | barcelona | spain   | europe | 10.0
 5  | paris     | france  | europe | 9.0
 23 | shanghai  | china   | asia   | 9.5
 54 | tokyo     | japan   | asia   | 9.3
 ...

示例模式..

CREATE TABLE cities (
    id int(11),
    city varchar(255),
    country varchar(255),
    region varchar(255),
    popular bool
);
INSERT INTO cities (id, city, country, region, popular)
VALUES  (1, 'barcelona', 'spain', 'europe', true),
        (3, 'rome', 'italy', 'europe', true),
        (5, 'paris', 'france', 'europe', true),
        (23, 'shanghai', 'spain', 'asia', true),
        (33, 'seoul', 'south-korea', 'asia', true),
        (54, 'tokyo', 'japan', 'asia', true);

CREATE TABLE nightlife (
    cityID int,
    rating float
);
INSERT INTO nightlife (cityID, rating)
VALUES  (1, 10.0),
        (3, 8.3),
        (5, 9.0),
        (23, 9.5),
        (33, 8.7),
        (54, 9.3);

和SQL小提琴相同......

http://sqlfiddle.com/#!9/ccc4e4

mysql join greatest-n-per-group row-number
3个回答
1
投票
SELECT n.id
     , n.city
     , n.country
     , n.region
     , n.popular
     , n.rating
  FROM 
     ( SELECT a.*
            , CASE WHEN @prev = region THEN @i:=@i+1 ELSE @i:=1 END i
            , @prev:=region prev 
         FROM
            ( SELECT c.*
                   , n.rating
                FROM cities c 
                JOIN nightlife n 
                  ON n.cityid = c.id 
               ORDER 
                  BY region
                   , rating DESC
            ) a
         JOIN ( SELECT @prev:=null,@i:=0) vars
      ) n
  WHERE n.i <= 2;

  +------+-----------+---------+--------+---------+--------+
  | id   | city      | country | region | popular | rating |
  +------+-----------+---------+--------+---------+--------+
  |   23 | shanghai  | spain   | asia   |       1 |    9.5 |
  |   54 | tokyo     | japan   | asia   |       1 |    9.3 |
  |    1 | barcelona | spain   | europe |       1 |     10 |
  |    5 | paris     | france  | europe |       1 |      9 |
  +------+-----------+---------+--------+---------+--------+

0
投票

您可以尝试使用UNION声明来获得该地区的FIRST和SECOND最佳城市。要获得第二高的值,我使用this SO答案

SELECT  C.region, C.city, C.id, MAX(N.rating) as rating
FROM   cities C
INNER JOIN nightlife N
ON         C.ID = N.cityID 
GROUP BY C.region
UNION 
SELECT  C.region, C.city, C.id, MAX(N.rating) as rating
FROM   cities C
INNER JOIN nightlife N
ON         C.ID = N.cityID 
WHERE N.rating < (SELECT MAX(rating) 
                  FROM   nightlife 
                  INNER JOIN cities 
                  ON cities.ID = nightlife.cityID 
                  WHERE region = c.region)
GROUP BY C.region
ORDER BY region,rating desc,city

这是工作解决方案fiddle


-1
投票

我的理解你的问题是你想要评价数据与城市细节的desc顺序:

    select b.city,b.country,a.region,a.rating from
  (SELECT max(c.id) as city_id,
       c.region,
       max(n.rating) as rating from cities c
  JOIN nightlife n
ON n.cityID = c.id
WHERE c.popular = true
group by c.region
ORDER BY n.rating
DESC) a inner join cities b on a.city_id=b.id;
© www.soinside.com 2019 - 2024. All rights reserved.