0

I would like get 3 random stamps, but each from different country. This query return random stamps, but could be from the same country. When I add GROUP BY country_id I will get 3 stamps of different countries, but only first stamps of each country.

SELECT `stamps`.`stamp_id`, `countries`.`country_name_cs` FROM `stamps`
LEFT JOIN `countries` ON countries.country_id = stamps.country_id
WHERE (stamps.stamp_enabled = 1) ORDER BY rand() ASC LIMIT 3

Any idea?

Query profile (#Ezequiel Muns solution)

starting              0.000232
Opening tables        0.000047
System lock           0.000013
Table lock            0.000635
optimizing            0.000036
statistics            0.000022
preparing             0.000023
Creating tmp table    0.000293
executing             0.000004
Copying to tmp table  0.060066
Sorting result        0.013835
Sending data          0.089164
removing tmp table    0.000632
Sending data          0.000026
init                  0.000048
optimizing            0.000014
statistics            0.000061
preparing             0.000028
Creating tmp table    0.000326
executing             0.000004
Copying to tmp table  0.353176
Sorting result        0.000158
Sending data          0.000038
end                   0.000005
removing tmp table    0.000018
end                   0.000006
query end             0.000004
freeing items         0.000575
removing tmp table    0.002363
closing tables        0.000023
logging slow query    0.000004
cleaning up           0.000009

id      select_type       table      type       possible_keys       key         key_len     ref           rows      Extra
1       PRIMARY       <derived2>     ALL        NULL                NULL        NULL        NULL          12679     Using temporary; Using filesort
1       PRIMARY       c              eq_ref     PRIMARY             PRIMARY     4           s.country_id  1      
2       DERIVED       stamps         ALL        NULL                NULL        NULL        NULL          12679     Using where; Using temporary; Using filesort
4

2 回答 2

2
SELECT
    c.country_id,
    c.country_name_cs,
    s.stamp_id
FROM country c
    JOIN (
        SELECT * 
        FROM stamps
        WHERE stamp_enabled = 1
        ORDER BY RAND()
    ) AS s ON c.country_id = s.country_id
GROUP BY c.country_id, c.country_name_cs
ORDER BY RAND()
LIMIT 3;

您首先将所有国家加入到它们各自的邮票中,但顺序是随机的,然后通过修剪该列表到每个国家的第一个(随机选择的)邮票进行分组。外部查询的 ORDER BY 将您选择的国家/地区随机化,然后 LIMIT 仅返回 3。

就像大卫 Z 说的那样,效率低下。

于 2012-04-23T08:48:12.887 回答
1

您可以尝试以下查询,首先选择 3 个随机国家,使用混合戳表执行连接,然后按国家分组。效率不高,但适用于较小的数据集。

 SELECT
    mixed_stamp.stamp_id,
    random.country_name_cs
 FROM
    (SELECT * FROM stamps ORDER BY RAND()) AS mixed_stamp
 LEFT JOIN (SELECT country_id FROM countries ORDER BY RAND() LIMIT 3) random ON (random.country_id = mixed_stamp.country_id)
 GROUP BY random.country_id
于 2012-04-23T08:18:07.487 回答