7_20 day25 14min 静态属性

本文介绍了一个简单的Python类定义示例,通过定义一个Room类来表示房间,并计算其面积。该类接受房间名称、所有者及尺寸作为参数,并封装了一个用于计算面积的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

class Room:
tag=1
def __init__(self,name,owner,width,length,heigh):
self.name=name
self.owner=owner
self.width=width
self.length=length
self.heigh=heigh

@property
def cal_area(self):
# print('%s 住的 %s 总面积是%s' % (self.owner,self.name, self.width * self.length))
return self.width * self.length


r1=Room('厕所','alex',100,100,100000)
print(r1.cal_area) //100000

封装了,隐藏过程,可以像数据属性一样调用

转载于:https://www.cnblogs.com/yikedashuyikexiaocao/p/9339487.html

详细理解以下代码,我稍后与你沟通 -- 删除已存在的视图 DROP VIEW IF EXISTS bj_database.view_work_order_list_filter; -- 创建或替换视图 CREATE OR REPLACE VIEW bj_database.view_work_order_list_filter AS WITH -- 1. 生成日期维度:从前天到未来第7天(共10天) date_dimension AS ( SELECT DATE_SUB(CURDATE(), INTERVAL 2 DAY) AS target_date, 1 AS day_order UNION ALL SELECT DATE_SUB(CURDATE(), INTERVAL 1 DAY), 2 UNION ALL SELECT CURDATE(), 3 UNION ALL SELECT DATE_ADD(CURDATE(), INTERVAL 1 DAY), 4 UNION ALL SELECT DATE_ADD(CURDATE(), INTERVAL 2 DAY), 5 UNION ALL SELECT DATE_ADD(CURDATE(), INTERVAL 3 DAY), 6 UNION ALL SELECT DATE_ADD(CURDATE(), INTERVAL 4 DAY), 7 UNION ALL SELECT DATE_ADD(CURDATE(), INTERVAL 5 DAY), 8 UNION ALL SELECT DATE_ADD(CURDATE(), INTERVAL 6 DAY), 9 UNION ALL SELECT DATE_ADD(CURDATE(), INTERVAL 7 DAY), 10 ), -- 2. 定义班次维度(白班:8:00-20:00,夜班:20:00-次日8:00) shift_dimension AS ( -- 白班:当天 08:00 - 20:00 SELECT target_date, '白班' AS shift_type, TIMESTAMP(target_date, '08:00:00') AS shift_start, TIMESTAMP(target_date, '20:00:00') AS shift_end FROM date_dimension UNION ALL -- 夜班:当天 20:00 - 次日 08:00 SELECT target_date, '夜班' AS shift_type, TIMESTAMP(target_date, '20:00:00') AS shift_start, TIMESTAMP(DATE_ADD(target_date, INTERVAL 1 DAY), '08:00:00') AS shift_end FROM date_dimension ), -- 3. 获取每个工单在"今天"的最新状态(含:已完工、已挂起) latest_daily AS ( SELECT w.*, ROW_NUMBER() OVER (PARTITION BY w.workOrderNo ORDER BY w.updateTime DESC) AS rn FROM bj_database.work_order_daily w WHERE DATE(w.updateTime) = CURDATE() AND w.workOrderStatus IN ('已提交', '已开工', '拟制中', '已完工', '已挂起') ), current_status AS ( SELECT * FROM latest_daily WHERE rn = 1 ), -- 4. 获取前两天各班次的实际产出和目标产出(按班次切分) actual_by_shift AS ( SELECT w.workOrderNo, s.target_date, s.shift_type, MAX(w.outputQty) AS actual_output, ROUND( COALESCE( (CAST(MAX(w.taskQty) AS DECIMAL(10,2)) - CAST(MAX(w.outputQty) AS DECIMAL(10,2))) * GREATEST( TIMESTAMPDIFF(SECOND, GREATEST(w.scheduleStartDate, s.shift_start), LEAST(w.scheduleEndDate, s.shift_end) ), 0 ) / NULLIF(TIMESTAMPDIFF(SECOND, w.scheduleStartDate, w.scheduleEndDate), 0), 0 ), 2 ) AS target_output FROM bj_database.work_order_daily w JOIN shift_dimension s ON DATE(w.updateTime) = s.target_date AND ( (s.shift_type = '白班' AND HOUR(w.updateTime) >= 8 AND HOUR(w.updateTime) < 20) OR (s.shift_type = '夜班' AND (HOUR(w.updateTime) >= 20 OR HOUR(w.updateTime) < 8 AND DATE(w.updateTime) = DATE(s.shift_end))) ) WHERE DATE(w.updateTime) BETWEEN DATE_SUB(CURDATE(), INTERVAL 2 DAY) AND CURDATE() AND w.workOrderStatus IN ('已提交', '已开工', '拟制中', '已完工', '已挂起') GROUP BY w.workOrderNo, s.target_date, s.shift_type ), -- 5. 计算工单静态参数(责任人、线体、剩余数量等) work_order_params AS ( SELECT c.workOrderNo, c.prodplanId AS `批次`, -- 映射为“批次” COALESCE(m.line_name, c.lineCode) AS `线体`, -- 映射为“线体” c.itemNo AS `单板代码`, -- 映射为“单板代码” c.itemName AS `单板名称`, -- 映射为“单板名称” CAST(c.taskQty AS DECIMAL(10,2)) AS `计划总数`, CAST(c.outputQty AS DECIMAL(10,2)) AS `当前产出`, (CAST(c.taskQty AS DECIMAL(10,2)) - CAST(c.outputQty AS DECIMAL(10,2))) AS `剩余数量`, MIN(c.scheduleStartDate) AS scheduleStartDate, MAX(c.scheduleEndDate) AS scheduleEndDate, GREATEST(TIMESTAMPDIFF(SECOND, MIN(c.scheduleStartDate), MAX(c.scheduleEndDate)), 1) AS total_duration_seconds, COALESCE( pc.计调员, CASE WHEN c.factoryName = '河源' AND c.craftSection IS NOT NULL AND LOCATE('背板', c.craftSection) > 0 THEN '徐捷如' WHEN c.factoryName = '河源' AND c.itemName REGEXP '^PPC|^PA|^PD|^PN|^ZXSDR BS8800 C100 PSUB0' THEN '何东' WHEN c.factoryName = '河源' AND c.externalType IN ('ES', 'MSR(R10)', 'CLS', 'IC', 'MSTP') THEN '钟慧珊' WHEN c.factoryName = '河源' AND c.externalType = '5G-WS' THEN '无线' WHEN c.factoryName = '河源' AND c.externalType IN ( '5G_CMxU', '5G_COLT', '5G_CONT', 'A10', 'CHS', 'CPE', 'DSL', 'EODN', 'J10', 'ONT', 'POL', 'PON_MxU', 'PON_OLT', 'PONG', 'POND', 'OTN', 'ITPS', 'MSAP', 'CLOUD', 'CT', 'ESI', 'IAD', 'iCDN', 'uSmartView', 'VCS', 'VCT' ) THEN '肖应仲' WHEN c.factoryName = '河源' AND c.externalType IN ('C-SPN', 'IPRAN-A', 'SPN', 'D-SPN', 'IPRAN', 'IPTN') THEN '徐捷如' WHEN c.factoryName = '河源' AND c.externalType IN ('CDCG', 'DC_P', 'DPS', 'POWER', 'PS_S', 'SSE', 'TSE', '3GPLAT', 'DC_S', 'SE') THEN '祁思佳' WHEN c.factoryName = '河源' AND c.externalType = 'RRS' THEN '何东' WHEN c.factoryName = '深圳' AND c.externalType IN ('ITPS', 'RSS') THEN '江启一' WHEN c.factoryName = '深圳' AND c.externalType IN ('OTN', 'WDM') THEN '杨港会' WHEN c.factoryName = '深圳' AND c.externalType = 'CP' THEN '周旭升' ELSE '未分配' END ) AS `责任人`, c.factoryName AS `工厂`, c.craftSection AS `主工序`, l.`线体` IS NOT NULL AS is_valid_line FROM current_status c LEFT JOIN bj_database.line_mapping m ON c.lineCode = m.line_id LEFT JOIN bj_database.part_category pc ON c.factoryName = pc.工厂 AND LEFT(c.itemNo, 12) = LEFT(pc.单板代码, 12) LEFT JOIN bj_database.lineteamleader l ON COALESCE(m.line_name, c.lineCode) = l.`线体` WHERE c.scheduleStartDate IS NOT NULL AND c.scheduleEndDate IS NOT NULL GROUP BY c.workOrderNo, c.prodplanId, COALESCE(m.line_name, c.lineCode), c.itemNo, c.itemName, c.taskQty, c.outputQty, c.factoryName, c.craftSection, l.`线体`, pc.计调员, c.externalType, c.scheduleStartDate -- 已添加到 GROUP BY ), -- 6. 生成每个工单在每个班次的计划产出(按工时比例分配) planned_by_shift AS ( SELECT wp.workOrderNo, s.target_date, s.shift_type, ROUND( wp.`剩余数量` * GREATEST( TIMESTAMPDIFF(SECOND, GREATEST(wp.scheduleStartDate, s.shift_start), LEAST(wp.scheduleEndDate, s.shift_end) ), 0 ) / wp.total_duration_seconds, 2 ) AS planned_output FROM work_order_params wp JOIN shift_dimension s ON s.target_date BETWEEN DATE(wp.scheduleStartDate) AND DATE(wp.scheduleEndDate) WHERE wp.is_valid_line AND s.target_date <= DATE_ADD(CURDATE(), INTERVAL 7 DAY) ), -- 7. 合并实际产出(历史)和计划产出(未来) combined_by_shift AS ( -- 历史实际产出(前2天) SELECT workOrderNo, target_date, shift_type, actual_output, target_output, 0 AS planned_output, 'actual' AS data_type FROM actual_by_shift WHERE target_date >= DATE_SUB(CURDATE(), INTERVAL 2 DAY) UNION ALL -- 未来计划产出 SELECT workOrderNo, target_date, shift_type, 0 AS actual_output, 0 AS target_output, planned_output, 'planned' AS data_type FROM planned_by_shift ), -- 8. 最终输出:将班次数据横向展开为列(行转列) final_output AS ( SELECT wp.`批次`, wp.`线体`, wp.`单板代码`, wp.`单板名称`, wp.`计划总数`, wp.`当前产出`, wp.`责任人`, wp.`工厂`, wp.`主工序`, -- 前天 白班 COALESCE(MAX(CASE WHEN cs.target_date = DATE_SUB(CURDATE(), INTERVAL 2 DAY) AND cs.shift_type = '白班' THEN cs.actual_output END), 0) AS `前天白班实际产出`, COALESCE(MAX(CASE WHEN cs.target_date = DATE_SUB(CURDATE(), INTERVAL 2 DAY) AND cs.shift_type = '白班' THEN cs.target_output END), 0) AS `前天白班目标产出`, COALESCE(MAX(CASE WHEN cs.target_date = DATE_SUB(CURDATE(), INTERVAL 2 DAY) AND cs.shift_type = '白班' THEN cs.planned_output END), 0) AS `前天白班计划产出`, -- 前天 夜班 COALESCE(MAX(CASE WHEN cs.target_date = DATE_SUB(CURDATE(), INTERVAL 2 DAY) AND cs.shift_type = '夜班' THEN cs.actual_output END), 0) AS `前天夜班实际产出`, COALESCE(MAX(CASE WHEN cs.target_date = DATE_SUB(CURDATE(), INTERVAL 2 DAY) AND cs.shift_type = '夜班' THEN cs.target_output END), 0) AS `前天夜班目标产出`, COALESCE(MAX(CASE WHEN cs.target_date = DATE_SUB(CURDATE(), INTERVAL 2 DAY) AND cs.shift_type = '夜班' THEN cs.planned_output END), 0) AS `前天夜班计划产出`, -- 昨天 白班 COALESCE(MAX(CASE WHEN cs.target_date = DATE_SUB(CURDATE(), INTERVAL 1 DAY) AND cs.shift_type = '白班' THEN cs.actual_output END), 0) AS `昨天白班实际产出`, COALESCE(MAX(CASE WHEN cs.target_date = DATE_SUB(CURDATE(), INTERVAL 1 DAY) AND cs.shift_type = '白班' THEN cs.target_output END), 0) AS `昨天白班目标产出`, COALESCE(MAX(CASE WHEN cs.target_date = DATE_SUB(CURDATE(), INTERVAL 1 DAY) AND cs.shift_type = '白班' THEN cs.planned_output END), 0) AS `昨天白班计划产出`, -- 昨天 夜班 COALESCE(MAX(CASE WHEN cs.target_date = DATE_SUB(CURDATE(), INTERVAL 1 DAY) AND cs.shift_type = '夜班' THEN cs.actual_output END), 0) AS `昨天夜班实际产出`, COALESCE(MAX(CASE WHEN cs.target_date = DATE_SUB(CURDATE(), INTERVAL 1 DAY) AND cs.shift_type = '夜班' THEN cs.target_output END), 0) AS `昨天夜班目标产出`, COALESCE(MAX(CASE WHEN cs.target_date = DATE_SUB(CURDATE(), INTERVAL 1 DAY) AND cs.shift_type = '夜班' THEN cs.planned_output END), 0) AS `昨天夜班计划产出`, -- 今天 白班 COALESCE(MAX(CASE WHEN cs.target_date = CURDATE() AND cs.shift_type = '白班' THEN cs.actual_output END), 0) AS `今天白班实际产出`, COALESCE(MAX(CASE WHEN cs.target_date = CURDATE() AND cs.shift_type = '白班' THEN cs.target_output END), 0) AS `今天白班目标产出`, COALESCE(MAX(CASE WHEN cs.target_date = CURDATE() AND cs.shift_type = '白班' THEN cs.planned_output END), 0) AS `今天白班计划产出`, -- 今天 夜班 COALESCE(MAX(CASE WHEN cs.target_date = CURDATE() AND cs.shift_type = '夜班' THEN cs.actual_output END), 0) AS `今天夜班实际产出`, COALESCE(MAX(CASE WHEN cs.target_date = CURDATE() AND cs.shift_type = '夜班' THEN cs.target_output END), 0) AS `今天夜班目标产出`, COALESCE(MAX(CASE WHEN cs.target_date = CURDATE() AND cs.shift_type = '夜班' THEN cs.planned_output END), 0) AS `今天夜班计划产出` FROM work_order_params wp LEFT JOIN combined_by_shift cs ON wp.workOrderNo = cs.workOrderNo GROUP BY wp.`批次`, wp.`线体`, wp.`单板代码`, wp.`单板名称`, wp.`计划总数`, wp.`当前产出`, wp.`责任人`, wp.`工厂`, wp.`主工序` ) SELECT * FROM final_output;
08-02
<think>我们有一个复杂的SQL视图创建语句,它的目的是生成一个工单列表的过滤视图,包含每个工单在多个班次(白班和夜班)的实际产出、目标产出和计划产出。 视图名为:bj_database.view_work_order_list_filter 步骤分解: 1. 删除已存在的同名视图(如果存在) 2. 创建或替换视图,使用多个公共表表达式(CTE)逐步构建数据 以下是每个CTE的详细说明: 1. date_dimension: 生成一个日期维度表,包含从前天开始到未来第7天的日期(共10天),并标记顺序(1-10) 2. shift_dimension: 定义班次维度(白班和夜班),为每个日期生成两个班次,并计算每个班次的开始和结束时间戳 白班:当天08:00到当天20:00 夜班:当天20:00到次日08:00 3. latest_daily 和 current_status: - 从bj_database.work_order_daily表中获取每个工单在“今天”的最新状态(按更新时间倒序取第一条),状态在('已提交','已开工','拟制中','已完工','已挂起')中 - 然后current_status只取每个工单的最新记录(rn=1) 4. actual_by_shift: 计算前两天(包括今天?注意条件:前2天到当前日期)每个工单在每个班次的实际产出和目标产出 - 关联work_order_daily和shift_dimension,根据更新时间判断班次(白班:8-20点,夜班:20点-次日8点) - 按工单号、日期、班次分组,计算实际产出(取该班次内最大的outputQty)和目标产出(通过复杂的公式计算,公式解释如下): 目标产出 = (该工单的总任务量 - 该班次的实际产出) * (该班次内工单计划时间与班次时间重叠的时长) / (工单总计划时长) 注意:这里用GREATEST确保重叠时长非负,用NULLIF避免除以0。 5. work_order_params: 计算工单静态参数(如批次、线体、单板代码、单板名称、计划总数、当前产出、剩余数量、计划开始结束时间等) - 从current_status中取数据,并关联多个表(line_mapping, part_category, lineteamleader)来获取线体名称、责任人等。 - 责任人的确定逻辑复杂,根据工厂、工序、单板名称、外部类型等条件分配。 - 计算总持续时长(计划结束时间-计划开始时间,单位为秒),并标记是否为有效线体(在lineteamleader表中存在的线体) 6. planned_by_shift: 为每个有效线体的工单,在未来7天内(从今天开始)的每个班次上,计算计划产出 - 公式:剩余数量 * (工单计划时间与班次时间重叠的时长) / 工单总持续时长(秒) - 只生成未来7天内的班次(s.target_date <= 当前日期+7天) 7. combined_by_shift: 将实际产出(历史:前2天)和计划产出(未来:从今天开始的7天)合并 - 实际产出部分:来自actual_by_shift(只取前2天的数据) - 计划产出部分:来自planned_by_shift - 使用UNION ALL合并,并标记数据类型('actual'或'planned') 8. final_output: 将combined_by_shift的数据按班次横向展开(行转列),每个班次有3个字段(实际产出、目标产出、计划产出) - 使用条件聚合(CASE WHEN)将每个班次的数据变成列 - 涉及的日期:前天、昨天、今天(每个日期有白班和夜班) - 注意:这里只取到今天的夜班,未来班次(从明天开始)在combined_by_shift中也有,但在这个final_output中没有被选择(因为只选了前天、昨天、今天)。但根据combined_by_shift的生成,计划产出部分只生成了未来7天(包括今天),而这里只取了今天及之前的班次(因为条件中只写了前天、昨天、今天)。所以最终输出只包含过去两天和今天,共3天,每天2个班次,共6个班次。 9. 最后从final_output中查询所有字段 注意:该视图的最终输出列包括: - 批次、线体、单板代码、单板名称、计划总数、当前产出、责任人、工厂、主工序 - 以及6个班次(前天白班、前天夜班、昨天白班、昨天夜班、今天白班、今天夜班)的3个指标(实际产出、目标产出、计划产出) 问题:在actual_by_shift中,目标产出的计算逻辑比较复杂,而且似乎与常规理解的目标产出不同。它用(总任务量-实际产出)乘以重叠时间占比,这样计算的目标产出可能不是该班次的目标,而是该班次应该完成的部分(按时间比例分摊的剩余量)。但这里用“目标产出”命名,可能容易引起歧义。 另外,在combined_by_shift中,对于历史班次,我们使用actual_output和target_output(来自actual_by_shift),而计划产出为0;对于未来班次,实际产出和目标产出为0,使用planned_output。 在final_output中,我们只取前天、昨天、今天三个日期,每个日期两个班次,共6个班次,每个班次输出3个值(实际、目标、计划)。注意:对于今天,如果当前时间在白天,那么夜班的数据可能还没有,但计划产出会显示。 由于视图创建语句较长,且涉及多个CTE,我们需要注意每个CTE的依赖关系。 下面,我将对代码进行逐块解释,并指出可能的问题或优化点。 但是,由于代码较长,我们只重点解释几个关键部分: 1. 在actual_by_shift中,关联条件使用了时间判断班次: (s.shift_type = '白班' AND HOUR(w.updateTime) >= 8 AND HOUR(w.updateTime) < 20) OR (s.shift_type = '夜班' AND (HOUR(w.updateTime) >= 20 OR HOUR(w.updateTime) < 8 AND DATE(w.updateTime) = DATE(s.shift_end))) 这里夜班的判断中,对于跨天的情况,只取更新日期等于班次结束日期的那部分(即夜班结束当天的0-8点)。这样避免了跨天数据归属错误。 2. 在work_order_params中,责任人的分配逻辑复杂,使用了多个条件。如果part_category表中没有匹配,则根据工厂和外部类型(externalType)等条件分配责任人。 3. 在planned_by_shift中,计算计划产出时,使用了工单的计划时间范围与班次时间范围的重叠部分,按比例分配剩余数量。 4. 在final_output中,使用GROUP BY和条件聚合(MAX+CASE)将每个班次的数据变成列。 可能的问题: - 在actual_by_shift中,目标产出的计算方式是否合理?它似乎是在计算该班次应该完成的数量(按时间比例分摊),但命名为“目标产出”可能不准确。 - 在combined_by_shift中,实际产出部分只取前2天(包括今天?),但条件中写的是“WHERE target_date >= DATE_SUB(CURDATE(), INTERVAL 2 DAY)”,即从前天开始到当前日期(包括今天)。而计划产出部分则是未来7天(包括今天)。所以对于今天,既有实际产出(如果今天还没过完,那么实际产出可能是不完全的)也有计划产出(今天还没发生的班次,以及当前班次还没完成的部分)。但在final_output中,对于今天的班次,我们同时取了实际产出、目标产出和计划产出?这可能会造成混淆。 注意:在final_output中,对于今天的班次,我们同时显示了实际产出、目标产出和计划产出。但实际产出是到当前时间为止该班次的实际产出(如果班次还没结束,那么实际产出会继续增加),而计划产出是整个班次计划完成的数量。目标产出则是按时间比例分摊的剩余量(这个值在班次结束时应该等于实际产出?)。这样设计可能是为了对比。 由于代码较长,我们不再逐行解释,而是理解整个逻辑。 下面,我们根据要求,回答关于这个SQL的问题,并给出相关的问题。 注意:由于这是一个视图创建语句,我们无法直接运行,但可以分析其逻辑。 如果用户要求解释代码,我们已经做了分步解释。 现在,我们按照要求,最后提出相关问题。</think>### 详细代码解释 #### 1. **视图初始化** ```sql -- 删除已存在的视图 DROP VIEW IF EXISTS bj_database.view_work_order_list_filter; -- 创建或替换视图 CREATE OR REPLACE VIEW bj_database.view_work_order_list_filter AS ``` - 先删除同名视图(避免冲突),再创建新视图。 #### 2. **日期维度(CTE: `date_dimension`)** ```sql WITH date_dimension AS ( SELECT DATE_SUB(CURDATE(), INTERVAL 2 DAY) AS target_date, 1 AS day_order UNION ALL SELECT DATE_SUB(CURDATE(), INTERVAL 1 DAY), 2 -- ... 共10天(从前天到未来7天) ) ``` - 生成连续日期范围:从前天(`CURDATE()-2`)到未来第7天(`CURDATE()+7`)。 - `day_order` 用于标识日期顺序。 #### 3. **班次维度(CTE: `shift_dimension`)** ```sql shift_dimension AS ( -- 白班:当天 08:00-20:00 SELECT target_date, '白班', TIMESTAMP(target_date, '08:00:00'), TIMESTAMP(target_date, '20:00:00') FROM date_dimension UNION ALL -- 夜班:当天 20:00-次日 08:00 SELECT target_date, '夜班', TIMESTAMP(target_date, '20:00:00'), TIMESTAMP(DATE_ADD(target_date, INTERVAL 1 DAY), '08:00:00') FROM date_dimension ) ``` - 为每个日期定义两个班次: - **白班**:当日 08:00 至 20:00。 - **夜班**:当日 20:00 至次日 08:00(跨天处理)。 #### 4. **工单最新状态(CTE: `current_status`)** ```sql latest_daily AS ( SELECT w.*, ROW_NUMBER() OVER (PARTITION BY workOrderNo ORDER BY updateTime DESC) AS rn FROM bj_database.work_order_daily w WHERE DATE(updateTime) = CURDATE() AND workOrderStatus IN ('已提交', '已开工', '拟制中', '已完工', '已挂起') ), current_status AS (SELECT * FROM latest_daily WHERE rn = 1) ``` - 获取当天(`CURDATE()`)每个工单的最新状态记录(按 `updateTime` 倒序取第一条)。 - 过滤有效状态:`已提交`、`已开工`、`拟制中`、`已完工`、`已挂起`。 #### 5. **历史实际产出(CTE: `actual_by_shift`)** ```sql actual_by_shift AS ( SELECT w.workOrderNo, s.target_date, s.shift_type, MAX(w.outputQty) AS actual_output, -- 实际产出 ROUND( ... ) AS target_output -- 目标产出(按工时比例计算) FROM bj_database.work_order_daily w JOIN shift_dimension s ON DATE(w.updateTime) = s.target_date WHERE DATE(w.updateTime) BETWEEN DATE_SUB(CURDATE(), INTERVAL 2 DAY) AND CURDATE() GROUP BY w.workOrderNo, s.target_date, s.shift_type ) ``` - **实际产出**:取班次内工单的 `outputQty` 最大值。 - **目标产出**: - 公式:`(任务总量 - 实际产出) × (班次内有效工时) / (工单总计划时长)` - 使用 `GREATEST` 确保有效工时非负,`NULLIF` 避免除零错误。 - 关联条件:工单更新时间匹配班次日期,且通过时间范围判断班次类型。 #### 6. **工单静态参数(CTE: `work_order_params`)** ```sql work_order_params AS ( SELECT c.workOrderNo, c.prodplanId AS `批次`, COALESCE(m.line_name, c.lineCode) AS `线体`, c.itemNo AS `单板代码`, c.itemName AS `单板名称`, c.taskQty AS `计划总数`, c.outputQty AS `当前产出`, (c.taskQty - c.outputQty) AS `剩余数量`, -- 责任人逻辑(基于工厂/单板类型分配) COALESCE(pc.计调员, CASE WHEN c.factoryName='河源' AND ... THEN '徐捷如' WHEN ... THEN '何东' ELSE '未分配' END ) AS `责任人`, c.factoryName AS `工厂`, c.craftSection AS `主工序` FROM current_status c LEFT JOIN line_mapping m ON c.lineCode = m.line_id LEFT JOIN part_category pc ON c.factoryName = pc.工厂 AND LEFT(c.itemNo,12)=LEFT(pc.单板代码,12) WHERE c.scheduleStartDate IS NOT NULL AND c.scheduleEndDate IS NOT NULL ) ``` - 映射线体名称(优先使用 `line_mapping` 表)。 - 动态分配责任人(基于工厂、工序、单板类型等规则)。 - 计算关键静态指标:计划总数、当前产出、剩余数量。 #### 7. **未来计划产出(CTE: `planned_by_shift`)** ```sql planned_by_shift AS ( SELECT wp.workOrderNo, s.target_date, s.shift_type, ROUND(wp.`剩余数量` * GREATEST(TIMESTAMPDIFF(SECOND, GREATEST(wp.scheduleStartDate, s.shift_start), LEAST(wp.scheduleEndDate, s.shift_end)), 0) / wp.total_duration_seconds, 2) AS planned_output FROM work_order_params wp JOIN shift_dimension s ON s.target_date BETWEEN DATE(wp.scheduleStartDate) AND DATE(wp.scheduleEndDate) WHERE wp.is_valid_line ) ``` - **计划产出**:按工单在班次内的有效工时占比分摊剩余数量。 - 仅处理有效线体(`is_valid_line = TRUE`)。 #### 8. **合并历史与未来数据(CTE: `combined_by_shift`)** ```sql combined_by_shift AS ( -- 历史实际产出(前2天) SELECT workOrderNo, target_date, shift_type, actual_output, target_output, 0 AS planned_output, 'actual' FROM actual_by_shift UNION ALL -- 未来计划产出 SELECT workOrderNo, target_date, shift_type, 0, 0, planned_output, 'planned' FROM planned_by_shift ) ``` - **历史数据**(前2天):包含实际产出和目标产出。 - **未来数据**(未来7天):仅包含计划产出。 #### 9. **最终输出(横向展开班次数据)** ```sql final_output AS ( SELECT wp.`批次`, wp.`线体`, ..., -- 前天白班 COALESCE(MAX(CASE WHEN cs.target_date = DATE_SUB(CURDATE(), INTERVAL 2 DAY) AND cs.shift_type='白班' THEN cs.actual_output END), 0) AS `前天白班实际产出`, ..., -- 今天夜班 COALESCE(MAX(CASE WHEN cs.target_date = CURDATE() AND cs.shift_type='夜班' THEN cs.planned_output END), 0) AS `今天夜班计划产出` FROM work_order_params wp LEFT JOIN combined_by_shift cs ON wp.workOrderNo = cs.workOrderNo GROUP BY wp.`批次`, wp.`线体`, ... ) SELECT * FROM final_output; ``` - 将每个工单的班次数据**横向展开**为列(行转列)。 - 输出字段包括: - 静态参数:批次、线体、单板代码、责任人等。 - 动态指标:每个班次(前天白班/夜班、昨天白班/夜班、今天白班/夜班)的 **实际产出**、**目标产出**、**计划产出**。 --- ### 关键设计亮点 1. **时间范围覆盖完整** - 历史数据(前2天) + 未来计划(7天) = 共10天班次数据。 2. **动态责任人分配** - 基于工单属性(工厂/工序/单板类型)自动匹配责任人。 3. **跨天班次处理** - 夜班(20:00-次日08:00)的时间戳正确跨天。 4. **数据分区明确** - 历史班次:实际产出 + 目标产出。 - 未来班次:计划产出。 5. **防止除零错误** - 使用 `NULLIF` 和 `GREATEST` 确保计算安全。 --- ### 潜在优化建议 1. **班次时间硬编码** → 改用配置表管理。 2. **责任人规则复杂** → 抽离到单独映射表。 3. **工单状态过滤** → 增加状态码枚举表。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值