multiselect查询返回的行比预期的少

erhoui1w  于 2021-06-21  发布在  Mysql
关注(0)|答案(2)|浏览(471)

我正在尝试选择5个“最新”行(具有最高id的行),然后随机选择10个不应该是5个最新行中任何一个的行。

(SELECT t1.img_app_id 
 FROM imgs_app t1 
 ORDER BY t1.img_app_id DESC 
 LIMIT 5)
UNION
(SELECT t2.img_app_id 
 FROM imgs_app t2 
 ORDER BY RAND() DESC 
 LIMIT 10 OFFSET 5)

但出于某种原因,最后一个查询只返回7行?数据库当前总共有29行。
当我命令desc时,我应该首先得到最高的id,当我使用offset 5时,我不应该得到最新的5行中的任何一行,对吗?
在这个sql中我做错了什么?

owfi6suc

owfi6suc1#

UNION 两者的结合 SELECT 查询中的操作。如果您最近的五个查询返回相同的 id 值作为随机查询, UNION 抑制重复项。
尝试 UNION ALL .

6ljaweal

6ljaweal2#

请注意 ORDER BY RAND() DESC LIMIT 10 OFFSET 5 相当于 ORDER BY RAND() DESC LIMIT 5 OFFSET 0 ,也就是“5个随机行”。你也可以直接写 ORDER BY RAND() LIMIT 10 .
因此,对于第二部分,您需要在“洗牌”行之前“移除”另一个子查询中的前5行:

SELECT img_app_id 
FROM (
    SELECT img_app_id 
    FROM imgs_app
    ORDER BY img_app_id DESC 
    LIMIT 9999999999 OFFSET 5
) sub
ORDER BY RAND()
LIMIT 10

另一种方法(可能更快)是在where子句中使用子查询来“删除”前5行:

SELECT img_app_id 
FROM imgs_app
WHERE img_app_id <= (
    SELECT img_app_id
    FROM imgs_app
    ORDER BY img_app_id DESC
    LIMIT 1 OFFSET 5
)
ORDER BY RAND()
LIMIT 10

现在你可以用 UNION [DISTINCT] 或者 UNION ALL . 结果将是一样的,因为不能有任何重复。但是 UNION ALL 将避免不必要的排序。
最后一个问题是:

(
    SELECT t1.img_app_id 
    FROM imgs_app t1 
    ORDER BY t1.img_app_id DESC 
    LIMIT 5
) UNION ALL (
    SELECT img_app_id 
    FROM imgs_app
    WHERE img_app_id <= (
        SELECT img_app_id
        FROM imgs_app
        ORDER BY img_app_id DESC
        LIMIT 1 OFFSET 5
    )
    ORDER BY RAND()
    LIMIT 10
)

请注意 UNION ALL 阿隆不是解决办法。你只会得到一些随机的副本。

相关问题