import configparser import pandas as pd import sqlalchemy from sqlalchemy import create_engine from urllib.parse import quote_plus # 读取配置文件 config = configparser.ConfigParser() config.read('config.ini') # 获取数据库连接配置 source_config = { 'host': config.get('source_db', 'host'), 'user': config.get('source_db', 'user'), 'password': config.get('source_db', 'password'), 'database': config.get('source_db', 'database'), 'port': config.getint('source_db', 'port') } target_config = { 'host': config.get('target_db', 'host'), 'user': config.get('target_db', 'user'), 'password': config.get('target_db', 'password'), 'database': config.get('target_db', 'database'), 'port': config.getint('target_db', 'port') } def analyze_sql_and_output(): # 2. 建立数据库连接 # 创建数据库引擎 source_engine = create_engine( f"mysql+pymysql://{source_config['user']}:{quote_plus(source_config['password'])}@{source_config['host']}:{source_config['port']}/{source_config['database']}" ) target_engine = create_engine( f"mysql+pymysql://{target_config['user']}:{quote_plus(target_config['password'])}@{target_config['host']}:{target_config['port']}/{target_config['database']}" ) # 3. 定义SQL查询语句 collar_sql = """ SELECT bat.AGREEMENT_ID AS agreement_id, bmc.ID as lease_id, mm.TYPE as type_id, mm.ID as ma_id, ttm.CREATE_TIME as start_time, 1 as num, IF(bma.IS_BALANCE = 0,1,0) as is_slt, bma.SETTLEMENT_TIME as slt_time, mt.IS_COUNT, mt.lease_price FROM ba_ma_collar bmc LEFT JOIN ba_agreement_task bat on bmc.ID = bat.TASK_ID LEFT JOIN ba_ma_agreement bma on bat.AGREEMENT_ID = bma.ID LEFT JOIN tm_task_ma ttm on bmc.ID = ttm.TASK_ID LEFT JOIN ma_machines mm on ttm.MA_ID = mm.ID LEFT JOIN ma_type mt on mm.TYPE = mt.ID WHERE bmc.company_id =1 AND mt.IS_COUNT = 0 UNION SELECT bat.AGREEMENT_ID AS agreement_id, bmc.ID as lease_id, ttot.MA_TYPE_ID as type_id, null as ma_id, ttot.CREATE_TIME as start_time, ttot.NUM as num, IF(bma.IS_BALANCE = 0,1,0) as is_slt, bma.SETTLEMENT_TIME as slt_time, mt.IS_COUNT, mt.lease_price FROM ba_ma_collar bmc LEFT JOIN ba_agreement_task bat on bmc.ID = bat.TASK_ID LEFT JOIN ba_ma_agreement bma on bat.AGREEMENT_ID = bma.ID LEFT JOIN tm_task_out_type ttot on bmc.ID = ttot.TASK_ID LEFT JOIN ma_type mt on ttot.MA_TYPE_ID = mt.ID WHERE bmc.company_id =1 AND ttot.IS_COUNT =1; """ back_sql = """ SELECT bat.AGREEMENT_ID AS agreement_id, bmb.ID as back_id, mm.TYPE as type_id, mm.ID as ma_id, ttm.CREATE_TIME as end_time, 1 as num, mt.IS_COUNT FROM ba_ma_back bmb LEFT JOIN ba_agreement_task bat on bmb.ID = bat.TASK_ID LEFT JOIN ba_ma_agreement bma on bat.AGREEMENT_ID = bma.ID LEFT JOIN tm_task_ma ttm on bmb.ID = ttm.TASK_ID LEFT JOIN ma_machines mm on ttm.MA_ID = mm.ID LEFT JOIN ma_type mt on mm.TYPE = mt.ID WHERE mt.IS_COUNT = 0 UNION SELECT bat.AGREEMENT_ID AS agreement_id, bmb.id as back_id, ttmt.MA_TYPE_ID as type_id, null as maId, bmb.CREATE_TIME as end_time, ROUND(ttmt.MACHINES_NUM,3) as num, ttmt.IS_COUNT FROM ba_ma_back bmb LEFT JOIN ba_agreement_task bat on bmb.ID = bat.TASK_ID LEFT JOIN ba_ma_agreement bma on bat.AGREEMENT_ID = bma.ID LEFT JOIN tm_task_ma_type ttmt on bmb.ID = ttmt.TASK_ID LEFT JOIN pm_user pu on bmb.CREATOR = pu.ID WHERE ttmt.IS_COUNT =1 """ price_sql = """ SELECT ph.id, ph.type_id, ph.start_time, ph.end_time, ph.lease_price FROM lease_price_his ph WHERE is_active =1 """ # 4. 执行SQL查询获取原始数据 collar_df = pd.read_sql(collar_sql, source_engine) back_df = pd.read_sql(back_sql, source_engine) price_df = pd.read_sql(price_sql, source_engine) # 5. 处理数据,按照规则进行匹配 result_list = [] # 处理IS_COUNT=0的情况 count0_collar = collar_df[collar_df['IS_COUNT'] == 0] for _, row in count0_collar.iterrows(): # 在退料查询中查找相同的agreement_id和ma_id matched_back = back_df[(back_df['agreement_id'] == row['agreement_id']) & (back_df['ma_id'] == row['ma_id'])] if not matched_back.empty: end_time = matched_back.iloc[0]['end_time'] back_id = matched_back.iloc[0]['back_id'] status = '已退料' else: end_time = None back_id = None status = '未退料' # 检查租赁单价区间 lease_price = row['lease_price'] price_match = price_df[(price_df['type_id'] == row['type_id']) & (price_df['start_time'] <= row['start_time']) & (price_df['end_time'] >= row['start_time'])] if not price_match.empty: lease_price = price_match.iloc[0]['lease_price'] # 构建结果行 result_row = { 'agreement_id': row['agreement_id'], 'type_id': row['type_id'], 'ma_id': row['ma_id'], 'num': row['num'], 'start_time': row['start_time'], 'end_time': end_time, 'status': status, 'lease_id': row['lease_id'], 'back_id': back_id, 'lease_price': lease_price, 'buy_price': None, # 根据实际情况补充 'is_slt': row['is_slt'], 'slt_time': row['slt_time'] } result_list.append(result_row) # 处理IS_COUNT=1的情况 count1_collar = collar_df[collar_df['IS_COUNT'] == 1] for _, row in count1_collar.iterrows(): # 按时间顺序正序查找相同的agreement_id和type_id matched_backs = back_df[(back_df['agreement_id'] == row['agreement_id']) & (back_df['type_id'] == row['type_id'])].sort_values('end_time') remaining_num = float(row['num']) for _, back_row in matched_backs.iterrows(): if float(remaining_num) <= 0: break if back_row['num'] == remaining_num: # 数量相等,直接匹配 result_row = { 'agreement_id': row['agreement_id'], 'type_id': row['type_id'], 'ma_id': row['ma_id'], 'num': remaining_num, 'start_time': row['start_time'], 'end_time': back_row['end_time'], 'status': '已退料', 'lease_id': row['lease_id'], 'back_id': back_row['back_id'], 'lease_price': row['lease_price'], 'buy_price': None, 'is_slt': row['is_slt'], 'slt_time': row['slt_time'] } result_list.append(result_row) remaining_num = 0.0 elif float(back_row['num']) < remaining_num: # 退料数量小于领料数量,拆分 result_row1 = { 'agreement_id': row['agreement_id'], 'type_id': row['type_id'], 'ma_id': row['ma_id'], 'num': back_row['num'], 'start_time': row['start_time'], 'end_time': back_row['end_time'], 'status': '已退料', 'lease_id': row['lease_id'], 'back_id': back_row['back_id'], 'lease_price': row['lease_price'], 'buy_price': None, 'is_slt': row['is_slt'], 'slt_time': row['slt_time'] } result_list.append(result_row1) remaining_num -= float(back_row['num']) else: # 退料数量大于领料数量,匹配剩余部分 result_row = { 'agreement_id': row['agreement_id'], 'type_id': row['type_id'], 'ma_id': row['ma_id'], 'num': remaining_num, 'start_time': row['start_time'], 'end_time': back_row['end_time'], 'status': '已退料', 'lease_id': row['lease_id'], 'back_id': back_row['back_id'], 'lease_price': row['lease_price'], 'buy_price': None, 'is_slt': row['is_slt'], 'slt_time': row['slt_time'] } result_list.append(result_row) remaining_num = 0 # 处理未匹配完的领料 if float(remaining_num) > 0: result_row = { 'agreement_id': row['agreement_id'], 'type_id': row['type_id'], 'ma_id': row['ma_id'], 'num': remaining_num, 'start_time': row['start_time'], 'end_time': None, 'status': '未退料', 'lease_id': row['lease_id'], 'back_id': None, 'lease_price': row['lease_price'], 'buy_price': None, 'is_slt': row['is_slt'], 'slt_time': row['slt_time'] } result_list.append(result_row) # 6. 创建结果DataFrame并输出到目标表 result_df = pd.DataFrame(result_list) # 检查租赁单价区间并更新lease_price for idx, row in result_df.iterrows(): if pd.isna(row['start_time']): continue price_match = price_df[(price_df['type_id'] == row['type_id']) & (price_df['start_time'] <= row['start_time']) & (price_df['end_time'] >= row['start_time'])] if not price_match.empty: result_df.at[idx, 'lease_price'] = price_match.iloc[0]['lease_price'] # 输出到目标表 result_df.to_sql('slt_agreement_info', target_engine, if_exists='replace', index=False) print("数据处理完成,已输出到slt_agreement_info表") # 执行函数 analyze_sql_and_output()