点击上方【蓝色】字体 关注我们

01 场景描述
在 SQL 中,连接操作通常基于相等条件(如 JOIN... ON table1.column = table2.column
),这是等值连接。而非等值连接是指连接条件使用的不是相等运算符,例如>
、<
、BETWEEN
等。这种连接方式允许根据一定的范围或者顺序关系来关联两个表中的数据。- 单向近距离匹配
单向近距离匹配是一种特殊的非等值连接情况。假设我们有两个表,表 A 和表 B,单向近距离匹配是指对于表 A 中的每一条记录,在表 B 中找到与之最接近(按照某种距离度量,如数值差的绝对值)的一条记录,并且这种匹配是单向的,即只考虑从表 A 到表 B 的匹配,而不考虑从表 B 到表 A 的匹配。这种匹配方式在很多实际场景中都有应用,比如时间序列数据的匹配、地理位置数据的近似匹配等。

02 数据准备
create table t_1 as(select stack(6,1,2,4,5,8,10) as (a));create table t_2 as(select stack(5,2,3,7,11,13) as (b));
03 问题分析
select a, b, abs(a-b) diff, dense_rank() over (partition by a order by abs(a-b) )from t_1,t_2


select a, bfrom (select a, b, abs(a - b) diff, dense_rank() over (partition by a order by abs(a - b) ) rnfrom t_1,t_2) twhere rn = 1

04 小 结
非等值连接--单向近距离匹配应用
(1)时间序列数据分析
- 场景描述
在金融领域,有股票交易数据和公司财务报告发布日期的数据。股票交易数据包含交易日期( trade_date
)、股票代码(stock_code
)和交易价格(trade_price
)等字段;财务报告数据包含公司代码(company_code
,与股票代码相关)、报告发布日期(report_date
)和财务指标(如每股收益eps
)等字段。- 应用方式
单向近距离匹配可以用于为每个股票交易记录找到在交易日期之前最近发布的财务报告。通过非等值连接(如 trade_date >= report_date
)和计算日期差值(如DATEDIFF(trade_date, report_date)
),并选择差值最小的记录,可以分析交易价格与最新财务信息之间的关系。例如,投资者可以根据最新的财务报告来评估股票价格是否合理。
-- 假设已有股票交易表trades和财务报告表reports-- 找到每个交易记录对应的最近财务报告SELECTt.stock_code,t.trade_date,t.trade_price,r.report_date,r.epsFROMtrades tJOIN(SELECTt.id AS trade_id,MIN(DATEDIFF(t.trade_date, r.report_date)) AS min_date_diffFROMtrades tJOINreports r ON t.stock_code = r.company_code AND t.trade_date >= r.report_dateGROUP BYt.id) subquery ON t.id = subquery.trade_idJOINreports r ON t.stock_code = r.company_code AND DATEDIFF(t.trade_date, r.report_date) = subquery.min_date_diff;
- 场景描述
假设有一个商店位置数据表( store_locations
),包含商店编号(store_id
)、商店经度(store_longitude
)和纬度(store_latitude
);还有一个用户位置数据表(user_locations
),包含用户编号(user_id
)、用户经度(user_longitude
)和纬度(user_latitude
)。- 应用方式
可以使用单向近距离匹配来为每个用户找到最近的商店。这里的距离可以通过地理空间距离公式(如哈弗辛公式)来计算,不过为了简化,也可以先计算经度差和纬度差的绝对值之和作为距离的近似值。通过非等值连接和选择差值最小的记录,就可以找到每个用户最近的商店,这对于推荐附近的商店或者分析店铺的服务范围很有帮助。
-- 找到每个用户位置对应的最近商店位置SELECTu.user_id,u.user_longitude,u.user_latitude,s.store_id,s.store_longitude,s.store_latitudeFROMuser_locations uJOIN(SELECTu.id AS user_id,MIN(ABS(u.user_longitude - s.store_longitude) + ABS(u.user_latitude - s.store_latitude)) AS min_distanceFROMuser_locations uJOINstore_locations s ON 1 = 1 -- 这里可以添加更精确的地理范围筛选条件GROUP BYu.id) subquery ON u.id = subquery.user_idJOINstore_locations s ON ABS(u.user_longitude - s.store_longitude) + ABS(u.user_latitude - s.store_latitude) = subquery.min_distance;
- 场景描述
在制造业的供应链系统中,有原材料入库时间数据表( material_inventory
),包含物料编号(material_id
)、入库日期(in_date
)和入库数量(in_quantity
);还有生产订单数据表(production_orders
),包含订单编号(order_id
)、产品编号(product_id
)、生产开始日期(start_date
)和所需物料编号(required_material_id
)。- 应用方式
单向近距离匹配可以用于为每个生产订单找到在生产开始日期之前最近入库的原材料。通过非等值连接( start_date >= in_date
)和计算日期差值,选择差值最小的记录,能够确定生产订单所使用的原材料批次,这对于追溯产品质量、计算成本等方面非常重要。
-- 找到每个生产订单对应的最近入库原材料SELECTpo.order_id,po.start_date,po.required_material_id,mi.in_date,mi.in_quantityFROMproduction_orders poJOIN(SELECTpo.id AS order_id,MIN(DATEDIFF(po.start_date, mi.in_date)) AS min_date_diffFROMproduction_orders poJOINmaterial_inventory mi ON po.required_material_id = mi.material_id AND po.start_date >= mi.in_dateGROUP BYpo.id) subquery ON po.id = subquery.order_idJOINmaterial_inventory mi ON po.required_material_id = mi.material_id AND DATEDIFF(po.start_date, mi.in_date) = subquery.min_date_diff;
- 场景描述
考虑医院的病历数据( medical_records
),包含患者编号(patient_id
)、症状记录日期(symptom_date
)和症状描述(symptom_description
);还有检查报告数据(test_reports
),包含患者编号(patient_id
)、检查日期(test_date
)和检查结果(test_result
)。- 应用方式
单向近距离匹配可以为每个症状记录找到在症状记录日期之前最近的检查报告。这有助于医生更好地结合检查结果来分析患者的病情,通过非等值连接( symptom_date >= test_date
)和日期差值最小化的记录选择来实现。
-- 找到每个症状记录对应的最近检查报告SELECTmr.patient_id,mr.symptom_date,mr.symptom_description,tr.test_date,tr.test_resultFROMmedical_records mrJOIN(SELECTmr.id AS record_id,MIN(DATEDIFF(mr.symptom_date, tr.test_date)) AS min_date_diffFROMmedical_records mrJOINtest_reports tr ON mr.patient_id = tr.patient_id AND mr.symptom_date >= tr.test_dateGROUP BYmr.id) subquery ON mr.id = subquery.record_idJOINtest_reports tr ON mr.patient_id = tr.patient_id AND DATEDIFF(mr.symptom_date, tr.test_date) = subquery.min_date_diff;
会飞的一十六
微信号:ddan_hashcode
扫描右侧二维码关注我们
点个【在看】 你最好看

文章转载自会飞的一十六,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。






