如何通过MySQL查询获取20行含全屏与半屏的横幅数据?
解决方案
假设你的表名为banners,核心字段包含id(主键)、size(尺寸标识,值为'FULL'或'HALF')、image_url(图片地址)。以下提供两种适配不同需求的实现方案:
方案1:按视觉行分组拼接
通过窗口函数将半屏横幅两两分组,再与全屏横幅混合,最终取20个视觉行的布局。
查询语句
WITH half_groups AS ( SELECT image_url, size, FLOOR((ROW_NUMBER() OVER (ORDER BY id) - 1) / 2) AS group_id FROM banners WHERE size = 'HALF' ), half_pairs AS ( SELECT group_id, JSON_ARRAYAGG(image_url) AS half_images, 'HALF_PAIR' AS layout_type FROM half_groups GROUP BY group_id HAVING COUNT(*) = 2 -- 仅保留能凑成一对的半屏横幅 ), full_items AS ( SELECT image_url AS full_image, 'FULL' AS layout_type FROM banners WHERE size = 'FULL' ), combined_layout AS ( SELECT layout_type, full_image, NULL AS half_images FROM full_items UNION ALL SELECT layout_type, NULL, half_images FROM half_pairs ORDER BY id -- 按主键排序,可替换为RAND()实现随机布局 ) SELECT * FROM combined_layout LIMIT 20;
逻辑说明
half_groups:给半屏横幅按顺序分组,每2个为一组;half_pairs:将每组的两个半屏横幅用JSON数组拼接,标记为HALF_PAIR布局;full_items:提取所有全屏横幅,标记为FULL布局;- 合并两类布局后取前20行,得到刚好20个视觉行的结果。
方案2:精确控制视觉总行数
如果需要严格保证视觉行数不超过20,同时最大化利用空间,可以通过权重累计实现:
查询语句
WITH all_banners AS ( SELECT id, image_url, size, -- 全屏占1个视觉行,半屏占0.5个视觉行 CASE WHEN size = 'FULL' THEN 1 ELSE 0.5 END AS row_weight FROM banners ), cumulative_rows AS ( SELECT *, SUM(row_weight) OVER (ORDER BY id) AS total_visual_rows FROM all_banners ) SELECT id, image_url, size FROM cumulative_rows WHERE total_visual_rows <= 20;
逻辑说明
- 给每个横幅赋予行权重,通过累计权重计算,当累计值不超过20时停止查询,确保最终视觉行数刚好符合要求。
自定义调整建议
- 若需要固定交替布局(如示例中的FULL、HALF HALF循环),可给两类布局添加排序标识后按规则排列;
- 若允许单个半屏横幅填充一行,可去掉
half_pairs中的HAVING COUNT(*) = 2条件,由前端处理布局; - 排序字段可根据业务需求替换为发布时间、热度等字段。
内容的提问来源于stack exchange,提问作者Jeff Donchez
相关产品推荐
相关产品推荐

