WITH para AS ( -- ----找到pie维护的需要check什么参数的值--------- SELECT DISTINCT b.* ,a.FAB ,a.TEST_PROGRAM ,wp.WAT_PARAMETER_ID ,wp.NAME AS PARAMETER_NAME FROM (SELECT DISTINCT DRB_ID,PRODUCT_ID,LOT_ID, trim(STAGE) trim_stage,STATUS,CREATE_TIME, TRIM(REGEXP_SUBSTR(WAFER_ID,'[^,]+',1,LEVEL)) AS WAFER_ID FROM DRB_INFO_CONFIG dic WHERE STATUS = '0' CONNECT BY TRIM(REGEXP_SUBSTR(WAFER_ID,'[^,]+',1,LEVEL)) IS NOT NULL AND PRIOR WAFER_ID = WAFER_ID AND PRIOR PRODUCT_ID = PRODUCT_ID AND PRIOR DRB_ID = DRB_ID AND PRIOR LOT_ID = LOT_ID AND PRIOR DBMS_RANDOM.VALUE IS NOT NULL) b LEFT join ( SELECT DISTINCT FAB, PRODUCT_ID, PARAMETER_NAME, PARAMETER_MAPPING, LIMIT_FILE, TEST_PROGRAM, TRIM(REGEXP_SUBSTR(STAGE, '[^锛汸]+', 1, LEVEL)) AS STAGE_true FROM DRB_PARAMETER_MAPPING CONNECT BY LEVEL <= REGEXP_COUNT(STAGE, '锛汸') + 1 AND PRIOR PRODUCT_ID = PRODUCT_ID AND PRIOR FAB = FAB AND PRIOR TEST_PROGRAM = TEST_PROGRAM AND PRIOR PARAMETER_NAME = PARAMETER_NAME AND PRIOR SYS_GUID() IS NOT NULL ) a ON a.PRODUCT_ID = b.PRODUCT_ID AND a.STAGE_true = b.trim_stage LEFT JOIN WAT_PARAMETER wp ON a.PARAMETER_MAPPING = wp.NAME -- 对不对 ), -- -----------------查询是否有WAT数据,若有---------------------------- wat as( SELECT distinct l.LOTNO , b.trim_stage, concat(concat(substr(l.LOTNO,0,7),'-'),wwi.WAFER_NO) AS T_WAFER_ID, wwi.LOT_ID, WWI.WAFER_ID, WWI.WAFER_NO, WWI.TEST_PROGRAM, WWI.MEASURE_TIME FROM WAT_WAFER_INFO wwi LEFT JOIN LOT l ON wwi.LOT_ID = l.LOT_ID LEFT JOIN (SELECT DISTINCT DRB_ID,PRODUCT_ID,LOT_ID, trim(STAGE) trim_stage,STATUS,CREATE_TIME, TRIM(REGEXP_SUBSTR(WAFER_ID,'[^,]+',1,LEVEL)) AS WAFER_ID FROM DRB_INFO_CONFIG dic WHERE STATUS = '0' CONNECT BY TRIM(REGEXP_SUBSTR(WAFER_ID,'[^,]+',1,LEVEL)) IS NOT NULL AND PRIOR WAFER_ID = WAFER_ID AND PRIOR PRODUCT_ID = PRODUCT_ID AND PRIOR DRB_ID = DRB_ID AND PRIOR LOT_ID = LOT_ID AND PRIOR DBMS_RANDOM.VALUE IS NOT NULL) b ON b.LOT_ID = l.LOTNO WHERE wwi.LOT_ID IN ( -- 对应lotid “798360” SELECT DISTINCT LOT_ID FROM LOT WHERE -- 为什么要like,而不是一一对应 -- 取出DRBlot LOTNO IN (SELECT DISTINCT LOT_ID FROM DRB_INFO_CONFIG dic WHERE STATUS = '0') ) AND TRIM(concat(concat(substr(l.LOTNO,0,7),'-'),wwi.WAFER_NO)) IN ( SELECT DISTINCT TRIM(REGEXP_SUBSTR(WAFER_ID,'[^,]+',1,LEVEL)) FROM DRB_INFO_CONFIG dic WHERE STATUS = '0' CONNECT BY TRIM(REGEXP_SUBSTR(WAFER_ID,'[^,]+',1,LEVEL)) IS NOT NULL AND PRIOR WAFER_ID = WAFER_ID AND PRIOR DBMS_RANDOM.VALUE IS NOT NULL ) AND wwi.TEST_PROGRAM NOT LIKE '%M1%' AND wwi.TEST_PROGRAM NOT LIKE '%M4%' -- AND wwi.MEASURE_TIME > --大于DRB插入时间的lot order by wwi.measure_time DESC ) -- wat RAW data----------------- SELECT DISTINCT PTRO.* ,wws.* FROM ( SELECT para.FAB ,para.PRODUCT_ID ,p.PRODUCT_ID AS PRODUCT_NO ,wat.LOTNO ,wat.LOT_ID ,wat.trim_stage ,wat.T_WAFER_ID ,wat.WAFER_ID ,wat.WAFER_NO ,wat.TEST_PROGRAM ,wat.MEASURE_TIME ,para.DRB_ID ,para.STATUS ,para.CREATE_TIME ,para.TEST_PROGRAM ,para.WAT_PARAMETER_ID ,para.PARAMETER_NAME FROM wat LEFT JOIN para ON wat.LOTNO = para.LOT_ID AND wat.T_WAFER_ID = para.WAFER_ID AND wat.TRIM_STAGE = para.TRIM_STAGE --AND wat.TEST_PROGRAM = para.TEST_PROGRAM 暂时没法关联 WAT_PARAMETER_ID也没法关联 LEFT JOIN PRODUCT p ON para.PRODUCT_ID = p.NAME ) ptro LEFT JOIN WAT_WAFER_SUMMARY wws ON ptro.PRODUCT_NO = WWS.PRODUCT_ID AND ptro.LOT_ID = WWS.LOT_ID AND ptro.WAFER_ID = WWS.WAFER_ID AND ptro.WAT_PARAMETER_ID = WWS.WAT_PARAMETER_ID ; 报错
时间: 2025-06-20 08:18:09 浏览: 14
<think>嗯,用户给的这个SQL查询报错了,我需要仔细看看哪里出问题了。首先,用户提供的SQL比较复杂,涉及多个子查询和连接,可能需要逐步分析。
首先,检查基本语法是否有错误。比如,有没有缺少关键字或者括号不匹配的情况。注意到在WITH子句中,para和wat是两个CTE(公共表表达式),然后最后的SELECT部分引用了这些CTE。结构上看起来没问题,但可能需要检查每个子查询的细节。
接下来,看看连接条件。在para的定义中,有几个LEFT JOIN,特别是连接DRB_PARAMETER_MAPPING和WAT_PARAMETER表的部分。用户注释中提到“对不对”,可能这里有问题。比如,ON a.PARAMETER_MAPPING = wp.NAME,是否正确?需要确认字段是否匹配,或者是否有数据类型不一致的问题。
然后,wat子查询中的CONCAT函数使用可能存在隐患。例如,concat(concat(substr(l.LOTNO,0,7),'-'),wwi.WAFER_NO)这里,Oracle的SUBSTR索引是从1开始还是0?如果Oracle的SUBSTR从1开始,那么substr(l.LOTNO,0,7)可能会返回空或者错误的值,导致T_WAFER_ID不正确,进而影响后续的连接。应该检查SUBSTR的起始位置是否正确,可能需要改为SUBSTR(l.LOTNO,1,7)。
另外,在wat的WHERE子句中,有一个TRIM(concat(...)) IN (SELECT ...)的条件。这里使用TRIM可能掩盖了数据中的空格问题,但如果原数据本身没有空格,可能没问题。不过更需要注意的是,这个子查询中的CONNECT BY层级查询是否正确,特别是PRIOR的使用是否正确,可能导致结果集异常。
还有,用户注释中提到“为什么要like,而不是一一对应”,在wat子查询的LOTNO IN (SELECT DISTINCT LOT_ID FROM DRB_INFO_CONFIG)中,可能LOTNO和LOT_ID的数据类型不一致,比如一个是VARCHAR而另一个是NUMBER,导致隐式转换错误。需要检查这两个字段的类型是否匹配,或者是否需要显式转换。
在最后的SELECT部分,连接WAT_WAFER_SUMMARY时使用了多个条件,包括ptro.WAT_PARAMETER_ID = WWS.WAT_PARAMETER_ID。如果WAT_PARAMETER_ID在para中可能为NULL(因为LEFT JOIN),那么与WWS的关联可能失败,导致结果缺失或错误。需要确认para中的WAT_PARAMETER_ID是否都能正确匹配到WWS中的值。
另外,检查是否有字段名重复导致的歧义。例如,para和wat中都有TEST_PROGRAM字段,在最终SELECT时使用了ptro.TEST_PROGRAM,可能需要使用别名来区分,避免歧义。
还有,用户提到报错,但具体错误信息没有给出。如果有ORA-00904之类的错误,可能是字段名拼写错误或不存在。需要逐一检查所有引用的字段是否在对应的表中存在,特别是大小写是否匹配(Oracle默认是大写)。
最后,考虑性能问题,复杂的CONNECT BY和多个LEFT JOIN可能导致执行计划效率低下,尤其是在处理大量数据时。可能需要优化查询结构,或者添加索引。</think>这个SQL查询的报错可能涉及多个方面,以下是逐步排查和优化建议:
---
### **一、语法与连接问题**
#### 1. **SUBSTR起始位置问题**
在`wat`子查询中存在隐患:
```sql
concat(substr(l.LOTNO,0,7),'-') --Oracle的SUBSTR起始位置是1
```
应改为:
```sql
concat(substr(l.LOTNO,1,7),'-') --从第1个字符开始取7位
```
#### 2. **隐式数据类型转换**
在以下条件中:
```sql
WHERE wwi.LOT_ID IN (SELECT DISTINCT LOT_ID FROM LOT WHERE LOTNO IN (...))
```
- 检查`LOTNO`(可能为VARCHAR)和`LOT_ID`(可能为NUMBER)是否类型一致。
- 如果需要,使用显式转换:
```sql
WHERE TO_CHAR(wwi.LOT_ID) IN (SELECT TO_CHAR(LOTNO) FROM ...)
```
---
### **二、逻辑问题**
#### 1. **连接条件缺失**
在最终查询的`LEFT JOIN para`时缺少关键关联:
```sql
ON wat.LOTNO = para.LOT_ID
AND wat.T_WAFER_ID = para.WAFER_ID
AND wat.TRIM_STAGE = para.TRIM_STAGE
-- 缺少TEST_PROGRAM关联可能导致数据错位
```
建议补充:
```sql
AND wat.TEST_PROGRAM = para.TEST_PROGRAM --若逻辑允许
```
#### 2. **参数映射问题**
在`para`定义中:
```sql
LEFT JOIN WAT_PARAMETER wp ON a.PARAMETER_MAPPING = wp.NAME
```
- 确认`PARAMETER_MAPPING`字段是否真的与`WAT_PARAMETER.NAME`匹配。
- 如果关联失败,`WAT_PARAMETER_ID`会为NULL,导致后续关联失效。
---
### **三、性能问题**
#### 1. **CONNECT BY递归查询**
在拆分`WAFER_ID`时:
```sql
CONNECT BY TRIM(REGEXP_SUBSTR(WAFER_ID,'[^,]+',1,LEVEL)) IS NOT NULL
AND PRIOR WAFER_ID = WAFER_ID
AND PRIOR DBMS_RANDOM.VALUE IS NOT NULL
```
- `PRIOR DBMS_RANDOM.VALUE`是无效写法,可能导致递归失控。
- 应改为标准层级查询:
```sql
CONNECT BY LEVEL <= REGEXP_COUNT(WAFER_ID, ',') + 1
```
---
### **四、建议优化**
1. **分步调试**
- 单独执行`para`和`wat`子查询,验证中间结果是否合理。
- 检查`WAT_PARAMETER_ID`是否为空(可能因连接失败导致)。
2. **显式字段别名**
```sql
SELECT
para.FAB AS PARA_FAB,
wat.TEST_PROGRAM AS WAT_TEST_PROGRAM,
...
```
3. **添加索引**
- 在`DRB_INFO_CONFIG`表的`STATUS`、`LOT_ID`字段添加索引。
- 在`WAT_WAFER_INFO`表的`LOT_ID`、`WAFER_NO`字段添加索引。
---
### **五、常见错误场景**
- **ORA-00904: 无效标识符**:检查字段名拼写(如`TRIM_STAGE` vs `trim_stage`)。
- **ORA-01722: 无效数字**:确认`LOTNO`与`LOT_ID`类型是否一致。
- **递归查询超时**:优化`CONNECT BY`条件,限制层级。
如果提供具体报错信息,可以进一步定位问题。
阅读全文
相关推荐


















