一个很骚的sql报错:分页查询,每次返回数据可能不同

本文探讨了在使用相同SQL进行分页查询时,因排序字段位于辅表导致多次点击查询结果不一致的问题。通过调整主辅表位置及优化查询结构,有效解决了数据差异现象,并提供了在实际场景中对主辅表进行合理配置的建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

追加:

        不是主要问题,应该是排序字段缺少唯一值,后面加了rowid,生效了


主表:bdg_budget_project

辅表:bdg_budget

关系:一对一关系

问题:相同sql ,分页查询,多次点击,返回的数据可能不同

原因:排序字段是辅表的字段【具体原理暂时没弄明白,大概是因为排序操作的触发时间 和 辅表数据应该会随主表进行变化】

SELECT
	id,
	name
FROM
	(
	SELECT
		TMP.*,
		ROWNUM ROW_ID
	FROM
		(
		SELECT
			a.id,
			a.budget_id,
			a.project_id,
			a.name,
			b.bdg_status_type,
			b.bdg_status_name
		FROM
			bdg_budget_project a
		LEFT JOIN bdg_budget b ON a.budget_id = b.id
		WHERE
			b.budget_at = 2022
			AND b.deleted_flag = 0
		ORDER BY
			b.INSTITUTION_ID_PATH ASC,
			b.register_at DESC ) TMP
	WHERE
		ROWNUM <= 40)
WHERE
	ROW_ID > 20

解决:因为排序字段是固定的,只能从bdg_budget表获取字段,所以需要将bdg_budget放到主表的位置,既主表位置与辅表位置调换

SELECT
	id,
	name
FROM
	(
	SELECT
		TMP.*,
		ROWNUM ROW_ID
	FROM
		(
		SELECT
			a.id,
			a.budget_id,
			a.project_id,
			a.name,
			b.bdg_status_type,
			b.bdg_status_name
		FROM
			bdg_budget b
		LEFT JOIN bdg_budget_project a ON
			a.budget_id = b.id
		WHERE
			b.budget_at = 2022
			AND b.deleted_flag = 0
		ORDER BY
			b.INSTITUTION_ID_PATH ASC,
			b.register_at DESC ) TMP
	WHERE
		ROWNUM <= 40)
WHERE
	ROW_ID > 20

注意:

        若辅表需要过滤,其实可以考虑将过滤条件添加至 ON 后,进行 AND 操作;可以缩小辅表的数据量,减少关联时的对比次数,但无论辅表是否存在符合要求的数据,最终都会查出主表的数据量;

        如果将限制条件放到 WHERE 后,则此时是对关联后的结果集进行筛选,数据量可能会减少;

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值