– 将整个查询包装为子查询,在外部进行排序 SELECT ID, 工单号, 线别, 发生日期, 不具合分类, 五感分类, 指出者, 工序号, 异常分类, 问题点, 原因, 暂定对策, 实施者, 本质问题, 现场挑战项目, 预定完成日期, 恒久对策, 担当, 实际完成, 问题跟进类型, GL确认, 要件关联, – 添加排序用的实际完成日期列 TRY_CONVERT(DATE, 实际完成) AS 排序用实际完成 FROM ( – 第一个查询部分 SELECT ID, ‘’ AS 工单号, 线别, TRY_CONVERT(DATE, 发生日期) AS 发生日期, 不具合分类, 五感分类, 指出者, 工序号, case when 异常分类 is null then ‘日常’ else 异常分类 end as 异常分类, 问题点, 原因, 暂定对策, 实施者, CASE WHEN 本质问题 = ‘0’ THEN NULL ELSE 本质问题 END AS 本质问题, 现场挑战项目, TRY_CONVERT(DATE, 预定完成) AS 预定完成日期, 恒久对策, 担当, 实际完成, 问题跟进类型, GL确认, 要件关联 FROM [dbo].[dwd_问题点跟进表] WHERE 1=1 i f ( l e n ( 开始日期 ) = = 0 , " " , " A N D T R Y C O N V E R T ( D A T E , 发生日期 ) > = T R Y C O N V E R T ( D A T E , ′ " + 开始日期 + " ′ , 120 ) " ) if(len(开始日期)==0,"","ANDTRY C ONVERT(DATE,发生日期)>=TRY C ONVERT(DATE, ′ "+开始日期+" ′ ,120)"){if(len(结束日期) == 0,“”,“AND TRY_CONVERT(DATE, 发生日期) <= TRY_CONVERT(DATE, '” + 结束日期 + “', 120)”)} i f ( l e n ( 问题跟进类型 ) = = 0 , " " , " A N D 问题跟进类型 I N ( ′ " + 问题跟进类型 + " ′ ) " ) if(len(问题跟进类型)==0,"","AND问题跟进类型IN( ′ "+问题跟进类型+" ′ )"){if(len(工单号)==0,“”,“AND 工单号 IN ('” + 工单号 + “')”)} i f ( l e n ( 要件关联 ) = = 0 , " " , " A N D 要件关联 I N ( ′ " + 要件关联 + " ′ ) " ) if(len(要件关联)==0,"","AND要件关联IN( ′ "+要件关联+" ′ )"){if(len(实际完成)==0,“”,“AND 实际完成 IN ('” + 实际完成 + “')”)} i f ( l e n ( 问题来源 ) = = 0 , " " , " A N D 异常分类 I N ( ′ " + 问题来源 + " ′ ) " ) if(len(问题来源)==0,"","AND异常分类IN( ′ "+问题来源+" ′ )"){if(len(月份)==0,“”,“AND SUBSTRING(CONVERT(VARCHAR(10), TRY_CONVERT(DATE, 发生日期), 120), 6, 2) = '” + 月份 + “'”)} $ UNION ALL -- 第二个查询部分 SELECT NULL AS ID, 工单号, 生产线 AS 线别, TRY_CONVERT(DATE, 发生日期) AS 发生日期, 问题分类 AS 不具合分类, 五感分类, 实施人 AS 指出者, 工序 AS 工序号, 问题点分类 AS 异常分类, 问题点, 原因, 对策 AS 暂定对策, 实施部门 AS 实施者, CASE WHEN 本质问题 = '0' THEN NULL ELSE 本质问题 END AS 本质问题, 现场挑战 AS 现场挑战项目, TRY_CONVERT(DATE, 预计完成时间) AS 预定完成日期, 恒久对策, 跟进者 AS 担当, CASE WHEN TRY_CONVERT(DATE, 发生日期) < '2025-08-25' THEN CASE WHEN TRY_CONVERT(DATE, 实际完成时间) IS NOT NULL THEN TRY_CONVERT(DATE, 发生日期) ELSE TRY_CONVERT(DATE, 实际完成时间) END ELSE TRY_CONVERT(DATE, 实际完成时间) END AS 实际完成, 问题类型 AS 问题跟进类型, 作业状态 AS GL确认, 要件关联 FROM ( SELECT a.工单号, CASE WHEN a.生产线='缸体_TNGA1线' THEN '1#' WHEN a.生产线='缸体_TNGA2线' THEN '2#' END AS 生产线, TRY_CONVERT(DATE, a.创建时间) AS 发生日期, 问题分类, 五感分类, 实施人, 工序, CASE WHEN 台账号 IS NULL THEN '日常' ELSE 'TPM' END AS 问题点分类, 问题点, CASE WHEN 原因 IS NULL OR b.故障原因 IS NULL THEN '' ELSE CONCAT(原因, b.故障原因) END AS 原因, CASE WHEN 对策 IS NULL OR b.作业内容 IS NULL THEN '' ELSE CONCAT(对策, b.作业内容) END AS 对策, 实施部门, 本质问题, 现场挑战, TRY_CONVERT(DATE, 预计完成时间) AS 预计完成时间, 恒久对策, CASE WHEN 跟进者 IS NULL OR 维修担当 IS NULL THEN '' ELSE CONCAT(跟进者, 维修担当) END AS 跟进者, CASE WHEN 实际完成时间 IS NULL and a.作业状态='已完成' then CONVERT(DATE, a.创建时间) else 实际完成时间 END AS 实际完成时间, 问题类型, a.作业状态, 要件关联 FROM [dbo].[dwd_自主保全_点检异常问题上报] a LEFT JOIN dwd_突发保全一览 b ON b.来源单号 = a.工单号 WHERE a.生产线 IN ('缸体_TNGA1线','缸体_TNGA2线') ) 合并 UNION ALL -- 第三个查询部分 SELECT NULL AS ID, 工单号, 线别, TRY_CONVERT(DATE, 发生日期) AS 发生日期, NULL AS 不具合分类, NULL AS 五感分类, 指出者, 工序号 AS 工序号, case when 工单号 like 'TF%' then '突发' else '自主' end as 异常分类, 问题点, 原因, 暂定对策, NULL AS 实施者, NULL AS 本质问题, NULL AS 现场挑战项目, NULL AS 预定完成日期, NULL AS 恒久对策, 担当, TRY_CONVERT(DATE, GL确认) AS 实际完成, NULL AS 问题跟进类型, NULL AS GL确认, NULL AS 要件关联 FROM ( SELECT a.管理号 AS 工单号, CASE WHEN a.生产线='缸体_TNGA1线' THEN '1#' WHEN a.生产线='缸体_TNGA2线' THEN '2#' END AS 线别, TRY_CONVERT(DATE, a.故障发生时间) AS 发生日期, a.创建人 AS 指出者, a.工序号, a.故障描述 AS 问题点, a.故障原因 AS 原因, b.作业内容 AS 暂定对策, a.申报人 AS 担当, convert(date,b.设备恢复时间) AS 实际完成, b.作业状态 AS GL确认 FROM [dbo].[dws_设备_突发保全一览] a LEFT JOIN [dbo].[dwd_突发保全一览] b ON a.管理号 = b.突发保全单号 WHERE a.生产线 IN ('缸体_TNGA1线','缸体_TNGA2线') AND TRY_CONVERT(DATE, a.故障发生时间) >= '2025-09-01' ) AS 合并2 ) AS CombinedResults – 所有UNION结果包装为子查询 WHERE 1=1 i f ( l e n ( 开始日期 ) = = 0 , " " , " A N D T R Y C O N V E R T ( D A T E , 发生日期 ) > = T R Y C O N V E R T ( D A T E , ′ " + 开始日期 + " ′ , 120 ) " ) if(len(开始日期)==0,"","ANDTRY C ONVERT(DATE,发生日期)>=TRY C ONVERT(DATE, ′ "+开始日期+" ′ ,120)"){if(len(结束日期) == 0,“”,“AND TRY_CONVERT(DATE, 发生日期) <= TRY_CONVERT(DATE, '” + 结束日期 + “', 120)”)} i f ( l e n ( 问题跟进类型 ) = = 0 , " " , " A N D 问题类型 I N ( ′ " + 问题跟进类型 + " ′ ) " ) if(len(问题跟进类型)==0,"","AND问题类型IN( ′ "+问题跟进类型+" ′ )"){if(len(工单号)==0,“”,“AND 工单号 IN ('” +工单号+ “')”)} i f ( l e n ( 要件关联 ) = = 0 , " " , " A N D 要件关联 I N ( ′ " + 要件关联 + " ′ ) " ) if(len(要件关联)==0,"","AND要件关联IN( ′ "+要件关联+" ′ )"){if(len(实际完成)==0,“”,“AND TRY_CONVERT(DATE, 实际完成) IN (TRY_CONVERT(DATE, '” + 实际完成 + “', 120))”)} i f ( l e n ( 问题来源 ) = = 0 , " " , " A N D 问题分类 I N ( ′ " + 问题来源 + " ′ ) " ) if(len(问题来源)==0,"","AND问题分类IN( ′ "+问题来源+" ′ )"){if(len(月份)==0,“”,“AND SUBSTRING(CONVERT(VARCHAR(10), TRY_CONVERT(DATE, 发生日期), 120), 6, 2) = '” + 月份 + “'”)} ${if(len(指出者)==0,“”,“AND 实施人 IN ('” +指出者+ “')”)} ORDER BY 排序用实际完成 asc 这个语句没有起到效果:convert(date,b.设备恢复时间) AS 实际完成, b.作业状态 AS GL确认
时间: 2025-09-04 07:44:51 AIGC 浏览: 19
<think>
我们有一个复杂的SQL查询,它由三个部分通过UNION ALL组合而成,并且整个查询被包装为一个子查询,在外部进行排序。但是,用户报告说其中一个字段的转换没有起到效果:`convert(date,b.设备恢复时间) AS 实际完成`。
从用户提供的查询中,我们可以看到在第三个UNION ALL部分,有:
```sql
SELECT NULL AS ID,
工单号,
线别,
TRY_CONVERT(DATE, 发生日期) AS 发生日期,
NULL AS 不具合分类,
NULL AS 五感分类,
指出者,
工序号 AS 工序号,
case when 工单号 like 'TF%' then '突发' else '自主' end as 异常分类,
问题点,
原因,
暂定对策,
NULL AS 实施者,
NULL AS 本质问题,
NULL AS 现场挑战项目,
NULL AS 预定完成日期,
NULL AS 恒久对策,
担当,
TRY_CONVERT(DATE, GL确认) AS 实际完成, -- 注意这里,实际完成是从GL确认转换而来
NULL AS 问题跟进类型,
NULL AS GL确认,
NULL AS 要件关联
FROM ( ... ) AS 合并2
```
而用户指出问题的是:`convert(date,b.设备恢复时间) AS 实际完成`,但在上面的子查询中,我们并没有直接使用这个别名,而是使用了`TRY_CONVERT(DATE, GL确认) AS 实际完成`。
实际上,在第三个查询的内部子查询中,我们确实有:
```sql
SELECT a.管理号 AS 工单号,
...,
convert(date,b.设备恢复时间) AS 实际完成, -- 这里将b.设备恢复时间转换为日期,并命名为实际完成
b.作业状态 AS GL确认
FROM ...
```
然后在外部查询中,我们使用了`TRY_CONVERT(DATE, GL确认) AS 实际完成`。这里的问题在于,内部子查询中已经将`b.设备恢复时间`转换成了日期并命名为`实际完成`,但是外部查询却使用了`GL确认`(它是`b.作业状态`,是一个字符串状态,而不是日期)来转换。
因此,错误在于:在第三个UNION ALL部分的外部查询中,实际完成字段应该是直接使用内部子查询的`实际完成`字段,而不是使用`GL确认`字段。
所以,应该将:
`TRY_CONVERT(DATE, GL确认) AS 实际完成`
改为:
`实际完成` 或者 `TRY_CONVERT(DATE, 实际完成)`(但内部已经是日期,所以可以直接用)
但是注意,内部子查询中已经将设备恢复时间转换成了日期(使用convert(date, ...)),所以我们可以直接使用该列。
因此,修改第三个UNION ALL部分的外部查询中的实际完成列为:
```sql
SELECT ...,
实际完成, -- 直接使用内部子查询的列
...
```
但是,我们注意到在第三个UNION ALL部分的外部查询中,我们使用了`TRY_CONVERT(DATE, GL确认) AS 实际完成`,这显然是不对的,因为GL确认是作业状态(字符串)。正确的应该是使用内部子查询中已经转换好的`实际完成`列。
所以,正确的写法应该是:
```sql
...
担当,
实际完成, -- 直接使用内部子查询中的实际完成列(已经转换为日期)
...
```
另外,在外部查询的WHERE条件中,也有对实际完成列的过滤条件,例如:
`${if(len(实际完成)==0,"","AND TRY_CONVERT(DATE, 实际完成) IN (TRY_CONVERT(DATE, '" + 实际完成 + "', 120))")}`
这里使用的是外部查询中的实际完成列,也就是我们希望的这个日期列。
所以,总结修改点为:
在第三个UNION ALL部分的外部查询中,将`TRY_CONVERT(DATE, GL确认) AS 实际完成` 改为 `实际完成`。
修改后的第三个UNION ALL部分如下:
```sql
UNION ALL
-- 第三个查询部分
SELECT
NULL AS ID,
工单号,
线别,
TRY_CONVERT(DATE, 发生日期) AS 发生日期,
NULL AS 不具合分类,
NULL AS 五感分类,
指出者,
工序号 AS 工序号,
case when 工单号 like 'TF%' then '突发' else '自主' end as 异常分类,
问题点,
原因,
暂定对策,
NULL AS 实施者,
NULL AS 本质问题,
NULL AS 现场挑战项目,
NULL AS 预定完成日期,
NULL AS 恒久对策,
担当,
实际完成, -- 修改这里:直接使用内部子查询的实际完成字段,注意内部已经是日期类型
NULL AS 问题跟进类型,
NULL AS GL确认,
NULL AS 要件关联
FROM (
SELECT
a.管理号 AS 工单号,
CASE WHEN a.生产线='缸体_TNGA1线' THEN '1#' WHEN a.生产线='缸体_TNGA2线' THEN '2#' END AS 线别,
TRY_CONVERT(DATE, a.故障发生时间) AS 发生日期,
a.创建人 AS 指出者,
a.工序号,
a.故障描述 AS 问题点,
a.故障原因 AS 原因,
b.作业内容 AS 暂定对策,
a.申报人 AS 担当,
convert(date, b.设备恢复时间) AS 实际完成, -- 内部已经转换
b.作业状态 AS GL确认
FROM [dbo].[dws_设备_突发保全一览] a
LEFT JOIN [dbo].[dwd_突发保全一览] b ON a.管理号 = b.突发保全单号
WHERE a.生产线 IN ('缸体_TNGA1线','缸体_TNGA2线')
AND TRY_CONVERT(DATE, a.故障发生时间) >= '2025-09-01'
) AS 合并2
```
这样修改后,第三个部分的实际完成字段就会正确显示内部转换的日期值了。
此外,我们注意到在外部查询的WHERE条件中,有对实际完成字段的过滤条件,使用的是:
`AND TRY_CONVERT(DATE, 实际完成) IN (TRY_CONVERT(DATE, '" + 实际完成 + "', 120))`
这个条件在第三个部分中也是可以正常工作的,因为实际完成已经是日期类型,但为了统一和避免转换错误,我们使用TRY_CONVERT是安全的(如果实际完成字段可能包含转换失败的NULL)。
另外,在外部查询的排序中,我们使用了在外部查询中添加的列:`TRY_CONVERT(DATE, 实际完成) AS 排序用实际完成`,然后按这个排序。这个列对所有三个部分都适用,包括第三个部分修改后的实际完成列(日期类型)。
所以,修改后的整个查询应该可以正确工作。
注意:由于查询很长,这里不重复整个查询,只给出修改的部分。
另外,用户还提到一个条件:`b.作业状态 AS GL确认`,在第三个部分的内部子查询中,这个字段被命名为`GL确认`,然后在外部查询中,我们将其设为了`NULL AS GL确认`,因为第三个部分不需要这个字段?所以这个字段在第三个部分中并没有出现在最终结果中。这可能是设计如此。
最后,我们还需要注意整个查询中动态条件的构建。在原始查询中,动态条件使用了字符串拼接,这种方式在SQL注入和语法错误上可能存在风险,但这不是当前问题的重点。
因此,我们只需要修改第三个UNION ALL部分中实际完成字段的引用即可。
</think>
根据您的查询和分析,问题出在第三个UNION部分的实际完成字段处理上。以下是修复方案和详细解释:
### 问题原因
在第三个UNION部分的子查询中:
```sql
convert(date,b.设备恢复时间) AS 实际完成,
b.作业状态 AS GL确认
```
但在外部查询中却错误地使用了:
```sql
TRY_CONVERT(DATE, GL确认) AS 实际完成 -- ❌ 错误地使用了GL确认字段
```
导致实际完成日期没有被正确传递。
### 修复后的代码
```sql
-- 修复第三个UNION部分(仅展示修改部分)
UNION ALL
SELECT
NULL AS ID,
工单号,
线别,
阅读全文
相关推荐













