You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从数据集A、B选取无重复ID随机样本的问题排查与解决

问题

我有两个数据集A和B,需求如下:

  • 先从A中选取10个ID唯一的随机样本(ID不重复,对应总行数可多于10);
  • 再从B中选取10个同样ID唯一的随机样本,且这些ID不能出现在从A选取的样本中。

我执行了以下步骤:

  1. 从A中获取10个不同ID的样本并取出对应行,存储为A_records:
select * from A t1 
inner join (select distinct id from A tablesample(10 rows)) t2 
where t1.id = t2.id 
-- 存储为A_records
  1. 创建临时视图B_pool,存储B中排除A_records里ID的可用样本池:
create or replace view B_pool as 
(select distinct id from B where B.Id not in (select distinct ID from A_records)
  1. 从B_pool中选取样本:
select * from B t1 
inner join (select distinct ID from B_pool tablesample(10 rows)) t2 
on t1.id = t2.id

按逻辑应该可行,但实际结果里B的样本仍包含A样本中的ID,请问怎么避免这种重复?

解决方案

你的问题根源在于两处逻辑漏洞:

  1. tablesample(10 rows)的抽样缺陷:它是按数据块抽样,无法保证精确抽取10个唯一ID,甚至可能抽到重复ID;若抽样后实际唯一ID数量不足10,后续B的过滤逻辑会直接失效。
  2. NOT IN的空值隐患:如果A_records中存在NULL的ID,NOT IN会返回空结果,导致B_pool的过滤完全失效,直接保留B的所有ID。

修正后的执行步骤如下:

步骤1:正确从A抽取10个唯一随机ID并获取对应行

用随机排序+限制数量的方式,精确获取10个唯一ID,避免tablesample的不确定性:

-- 先筛选10个唯一随机ID,再关联获取全量行
WITH A_unique_ids AS (
    SELECT DISTINCT id 
    FROM A 
    ORDER BY RANDOM() -- 不同数据库写法有差异,见下方说明
    LIMIT 10
)
SELECT A.* INTO A_records
FROM A
JOIN A_unique_ids ON A.id = A_unique_ids.id;

步骤2:创建正确的B可用样本池

改用NOT EXISTS替代NOT IN,彻底避免空值导致的过滤失效:

CREATE OR REPLACE VIEW B_pool AS
SELECT DISTINCT id 
FROM B
WHERE NOT EXISTS (
    SELECT 1 FROM A_records WHERE A_records.id = B.id
);

步骤3:从B_pool抽取10个唯一随机ID并获取对应行

同样用随机排序+限制数量的方式,确保抽取的ID唯一且不与A重复:

WITH B_selected_ids AS (
    SELECT id 
    FROM B_pool 
    ORDER BY RANDOM() -- 对应数据库替换成随机函数
    LIMIT 10
)
SELECT B.*
FROM B
JOIN B_selected_ids ON B.id = B_selected_ids.id;

数据库适配说明

不同数据库的随机排序函数需要替换:

  • PostgreSQL: ORDER BY RANDOM()
  • MySQL/MariaDB: ORDER BY RAND()
  • SQL Server: ORDER BY NEWID()
  • Oracle: ORDER BY DBMS_RANDOM.VALUE()

内容的提问来源于stack exchange,提问作者curiouscoder007

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 12:55:14