DL-week6

本文介绍了Python中的np.random.permutation函数,用于一维或多维数据的随机排列,以及math.floor函数实现向下舍入至整数。同时提到了np.zeros_like用于创建与给定矩阵维度相同的全零矩阵的用法。
要学明白的知识点:
np.random.permutation()

总体来说他是一个随机排列函数,就是将输入的数据进行随机排列,官方文档指出,此函数只能针对一维数据随机排列,对于多维数据只能对第一维度的数据进行随机排列。

math.floor(x)

将x向下舍入到最接近的整数

np.zeros_like(W)

构造一个和W相同维度的0矩阵

实例:
附带要学的知识:
这段 SQL 语句整体结构是合理的,但存在一些潜在的问题和可以优化的地方,特别是在子查询、日期比较、性能和可读性方面。以下是具体分析和建议: --- ### ✅ **功能简述** 该 SQL 查询的目的是: - 按员工和日期汇总每日工时; - 同时从子查询中获取特批工时和工时申诉数据; - 过滤条件为某月(2025-08)且员工在周汇总表中存在记录。 --- ### ❌ **存在的问题** #### 1. **子查询中日期比较未考虑时间偏移问题** 你之前提到:**`dl.download_time` 小于第二天早上7点时应算作前一天**,但在子查询中仍然使用: ```sql TO_CHAR(dl.download_time,'YYYY-MM-DD') = TO_CHAR(R.Operate_Day, 'YYYY-MM-DD') ``` 这会导致 **时间小于 7:00 的记录被错误地归类到当天**,而不是前一天。 ✅ **建议修改为:** ```sql TO_CHAR( CASE WHEN EXTRACT(HOUR FROM dl.download_time) < 7 THEN dl.download_time - INTERVAL '1 day' ELSE dl.download_time END, 'YYYY-MM-DD' ) = TO_CHAR(R.Operate_Day, 'YYYY-MM-DD') ``` --- #### 2. **子查询中多次访问同一张表,性能较差** 两个子查询都从 `mes.cnc_ncfile_dlrec` 查询数据,只是 `working_step` 条件不同。这种重复访问会降低性能,尤其是数据量大时。 ✅ **建议优化为单次查询 + 分组条件聚合:** ```sql LEFT JOIN ( SELECT emp_no, TO_CHAR( CASE WHEN EXTRACT(HOUR FROM download_time) < 7 THEN download_time - INTERVAL '1 day' ELSE download_time END, 'YYYY-MM-DD' ) AS dl_date, SUM(CASE WHEN working_step IN ('特批工时','特批工时(超差类)','特批工时(周)') THEN (original_minutes * work_time * wt_per) / 100 / 60 ELSE 0 END) AS 特批工时, SUM(CASE WHEN working_step IN ('工时计算异常','漏加工项目') THEN (original_minutes * work_time * wt_per) / 100 / 60 ELSE 0 END) AS 工时申诉 FROM mes.cnc_ncfile_dlrec WHERE is_delete = 0 AND state = 0 GROUP BY emp_no, dl_date ) DL ON DL.emp_no = R.Emp_No AND DL.dl_date = TO_CHAR(R.Operate_Day, 'YYYY-MM-DD') ``` 这样可以避免重复子查询,提高执行效率。 --- #### 3. **`trunc(R.Operate_Day,'MM') = TO_DATE('2025/08','yyyy/MM')` 可能影响索引使用** 虽然语法正确,但使用 `trunc` 函数可能导致无法使用 `R.Operate_Day` 上的索引。 ✅ **建议改写为范围查询:** ```sql R.Operate_Day >= DATE '2025-08-01' AND R.Operate_Day < DATE '2025-09-01' ``` 这样更利于索引命中,提升性能。 --- #### 4. **`r.Emp_No In (Select w.Emp_No ...)` 子查询建议优化** 如果 `mes.Wt_Week_Summary` 表数据量大,建议使用 `INNER JOIN` 替代 `IN` 子查询,更高效且易读。 ✅ **建议写法:** ```sql INNER JOIN ( SELECT DISTINCT Emp_No FROM mes.Wt_Week_Summary WHERE Week_Id LIKE '202508_%' ) W ON R.Emp_No = W.Emp_No ``` --- ### ✅ 总结建议修改点 | 问题 | 建议 | |------|------| | 日期偏移未处理 | 使用 `CASE WHEN EXTRACT(HOUR FROM ...) < 7` 调整日期 | | 子查询重复访问表 | 改为一次 JOIN 查询 + 分组条件聚合 | | `trunc()` 影响索引 | 改为日期范围查询 | | `IN` 子查询效率低 | 改为 `INNER JOIN` | --- ### ✅ 示例优化后 SQL(简化版) ```sql SELECT TO_CHAR(R.Operate_Day, 'YYYY-MM-DD') AS 日期, R.Emp_No 员工编号, R.Emp_Name 员工姓名, SUM(R.Java_Hours) 原始工时, 1 折扣, SUM(R.Java_Hours * R.Discount) 网页工时, COALESCE(DL.特批工时, 0) 特批工时, COALESCE(DL.工时申诉, 0) 工时申诉 FROM MES.RPT_DAIY_WORKTIME R INNER JOIN ( SELECT DISTINCT Emp_No FROM mes.Wt_Week_Summary WHERE Week_Id LIKE '202508_%' ) W ON R.Emp_No = W.Emp_No LEFT JOIN ( SELECT emp_no, TO_CHAR( CASE WHEN EXTRACT(HOUR FROM download_time) < 7 THEN download_time - INTERVAL '1 day' ELSE download_time END, 'YYYY-MM-DD' ) AS dl_date, ROUND(SUM(CASE WHEN working_step IN ('特批工时','特批工时(超差类)','特批工时(周)') THEN (original_minutes * work_time * wt_per) / 100 / 60 ELSE 0 END), 2) AS 特批工时, ROUND(SUM(CASE WHEN working_step IN ('工时计算异常','漏加工项目') THEN (original_minutes * work_time * wt_per) / 100 / 60 ELSE 0 END), 2) AS 工时申诉 FROM mes.cnc_ncfile_dlrec WHERE is_delete = 0 AND state = 0 GROUP BY emp_no, dl_date ) DL ON DL.emp_no = R.Emp_No AND DL.dl_date = TO_CHAR(R.Operate_Day, 'YYYY-MM-DD') WHERE R.Operate_Day >= DATE '2025-08-01' AND R.Operate_Day < DATE '2025-09-01' GROUP BY R.Operate_Day, R.Emp_No, R.Emp_Name, DL.特批工时, DL.工时申诉; ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值