将多表关联SQL转换为基于List与Dict的Jython代码(无Pandas)
多表关联SQL转Jython实现方案
前提说明
- Work、Budget为列表,每个元素建议解析为字段名-值的字典(样例为竖线分隔字符串,需先解析)
- Grade字典以
GRADE字段值为键,对应值为该职级的完整属性字典 - Office字典以
JOB字段值为键,对应值为该岗位的完整属性字典
实现步骤
1. 数据解析工具函数(针对竖线分隔的原始字符串)
先把列表中的字符串转换成字典,方便后续字段访问:
def parse_line(line, delimiter='|'): # 第一行识别为表头,后续行解析为字典 if not hasattr(parse_line, 'headers'): parse_line.headers = line.strip().split(delimiter) return None values = line.strip().split(delimiter) return dict(zip(parse_line.headers, values)) # 解析Work列表 parsed_work = [] for line in Work: item = parse_line(line) if item: parsed_work.append(item) # 重置表头,解析Budget列表 delattr(parse_line, 'headers') parsed_budget = [] for line in Budget: item = parse_line(line) if item: parsed_budget.append(item)
2. 预计算每个(INC, POS)组合的最新生效日期
提前统计所有INC+POS对应的最大EFFTDATE,避免重复计算:
# 存储每个(INC, POS)的最新生效日期 latest_efftdate = {} for work_item in parsed_work: key = (work_item['INC'], work_item['POS']) current_date = work_item['EFFTDATE'] # 样例日期格式为DD-MMM-YYYY,英文月份缩写的字符串排序与实际日期顺序一致,可直接比较 if key not in latest_efftdate or current_date > latest_efftdate[key]: latest_efftdate[key] = current_date
3. 多表关联查询(对应原SQL逻辑)
按照原SQL的关联条件筛选记录,收集目标字段:
result = [] for work_item in parsed_work: # 筛选当前Work记录是否为该INC+POS的最新生效记录 key = (work_item['INC'], work_item['POS']) if work_item['EFFTDATE'] != latest_efftdate.get(key): continue # 关联Budget:通过POS字段匹配 budget_item = None for b in parsed_budget: if b['POS'] == work_item['POS']: budget_item = b break if not budget_item: continue # 无匹配Budget记录,跳过 # 关联Office:通过Budget的JOBC字段匹配Office的JOB键 office_item = Office.get(budget_item['JOBC']) if not office_item: continue # 无匹配Office记录,跳过 # 关联Grade:通过Office的GRADE字段匹配Grade的键 grade_item = Grade.get(office_item['GRADE']) if not grade_item: continue # 无匹配Grade记录,跳过 # 收集原SQL指定的目标字段 result_item = { 'POS': work_item['POS'], 'INC': work_item['INC'], 'EMPL': work_item['EMPL'], 'COMP': work_item['COMP'], 'EmplStatus': work_item['EMPLSTATUS'], 'HRStatus': work_item['HRSTATUS'], 'FTE': work_item['FTE'], 'FCCODE': work_item['FCCODE'], 'Job': budget_item['JOBC'], 'WageLossPlan': work_item['WAGELOSSPLAN'], 'BCC': office_item['BCC'], 'BargainingUnit': budget_item['BARGAINUNIT'], 'STHOURSPDAY': budget_item['STHOURSPDAY'], 'HRRATE': work_item['HRRATE'], 'SALCODE': work_item['SALCODE'], 'SALSTEP': work_item['SALSTEP'], 'GRADE': grade_item['GRADE'], 'NUMBSTEPS': grade_item['NUMBSTEPS'], 'ENTRYDATE': work_item['ENTRYDATE'], 'HOLSCHEDULECODE': work_item['HOLSCHEDULECODE'], 'UNI': work_item['UNI'] } result.append(result_item)
4. 结果输出(可选)
如果需要打印结构化结果:
if result: # 打印表头 headers = list(result[0].keys()) print('|'.join(headers)) # 打印每条记录 for item in result: print('|'.join(item.values()))
关键细节说明
- 日期比较:样例中
DD-MMM-YYYY格式的日期字符串,英文月份缩写的排序逻辑与实际日期顺序一致,可直接用字符串比较;若为其他格式,需转换为datetime对象后再比较 - 关联逻辑严格对齐原SQL:
Budget.JOBC = Office.JOB、Office.GRADE = Grade.GRADE、Work.POS = Budget.POS,同时筛选Work中每个INC+POS的最新生效记录 - 容错处理:无匹配关联记录时直接跳过,避免抛出异常
内容的提问来源于stack exchange,提问作者TélérealiTV Scoop
相关产品推荐
相关产品推荐

