SQL JOIN:一对多映射下仅单次扣除数据的实现方法问询
实现方案
当然可以实现这个逻辑,核心是给目标分组内的行标记顺序,只对指定行执行扣除操作。以下是具体实现:
1. 测试数据准备
先创建并插入题目中的测试数据:
-- 创建TABLE1 CREATE TABLE TABLE1 (A1 VARCHAR(10), B1 VARCHAR(10), C1 INT, D1 INT); INSERT INTO TABLE1 VALUES ('XX', 'yy', 2010, 10), ('XX', 'zz', 2010, 20); -- 创建TABLE2 CREATE TABLE TABLE2 (A1 VARCHAR(10), C1 INT, D2 INT); INSERT INTO TABLE2 VALUES ('XX', 2010, 5);
2. 核心查询语句
通过窗口函数标记行顺序,仅对分组内第一行扣除D2的值:
SELECT t1.A1, t1.B1, t1.C1, t1.D1, CASE WHEN rn = 1 THEN t1.D1 - COALESCE(t2.D2, 0) ELSE t1.D1 END AS D1_NEW FROM ( -- 按A1、C1分组,给每组内的行按B1排序编号 SELECT *, ROW_NUMBER() OVER (PARTITION BY A1, C1 ORDER BY B1) AS rn FROM TABLE1 ) t1 LEFT JOIN TABLE2 t2 ON t1.A1 = t2.A1 AND t1.C1 = t2.C1 ORDER BY t1.B1;
3. 逻辑说明
ROW_NUMBER()函数给A1='XX'且C1='2010'的分组行按B1排序生成序号,确保yy行是组内第一行(序号1)。CASE WHEN只对序号为1的行执行D1 - D2的计算,其他行直接保留原D1值。COALESCE(t2.D2, 0)用来处理TABLE2无对应数据的情况,避免出现NULL值。
4. 预期结果
执行查询后会得到目标输出:
| A1 | B1 | C1 | D1 | D1_NEW |
|---|---|---|---|---|
| XX | yy | 2010 | 10 | 5 |
| XX | zz | 2010 | 20 | 20 |
内容的提问来源于stack exchange,提问作者Sandeep KS
相关产品推荐
相关产品推荐

