我正在为通用表的表运行报告。那么" ParameterValue"中的值字段将包含来自许多不同类型的数据。我想要做的只是执行转换,如果" ParameterName"列等于历史时间戳'。
这是我正在运行的查询...
WITH LogbookSourceObjects AS (
SELECT CAST(obj.NAME AS INT) as LogbookId, ObjectId
FROM PISourceObject obj
JOIN PISource s ON s.SourceID = obj.SourceId
WHERE s.Name ='DEDR' AND ISNUMERIC(obj.NAME) = 1
),
Comments AS (
SELECT lso.LogbookId,
c.CommentId,
c.CommentTypeId,
cd.Comment,
cd.CommentDetailTime,
u.FirstName,
u.LastName,
cp.ParameterValue,
p.Name,
CONVERT(DATETIMEOFFSET, cp.ParameterValue) AS HistorianTimestamp
FROM LogbookSourceObjects lso
JOIN PIComment c ON c.ObjectId = lso.ObjectId
JOIN PICommentDetail cd ON cd.CommentId = c.CommentId
JOIN PICommentType ct ON ct.CommentTypeId = c.CommentTypeId
JOIN PICommentParameter cp on cp.CommentId = c.CommentId
JOIN PIParameter p on cp.ParameterId = p.ParameterId
JOIN PIUser u on u.UserId = cd.UserId
WHERE p.Name ='Historian Timestamp')
SELECT * FROM COMMENTS
返回以下数据
╔═══════════╦═══════════╦═══════════════╦══════════════════╦═══════════════════╦═══════════╦══════════╦═══════════════════════════╦═════════════════════╦════════════════════════════════════╗
║ LogbookId ║ CommentId ║ CommentTypeId ║ Comment ║ CommentDetailTime ║ FirstName ║ LastName ║ ParameterValue ║ Name ║ HistorianTimestamp ║
╠═══════════╬═══════════╬═══════════════╬══════════════════╬═══════════════════╬═══════════╬══════════╬═══════════════════════════╬═════════════════════╬════════════════════════════════════╣
║ 1 ║ 2 ║ 1 ║ I entered 1 ║ 53:39.8 ║ Jason ║ Turan ║ 2016-11-29T12:47:14 ║ Historian Timestamp ║ 2016-11-29 12:47:14.0000000 +00:00 ║
║ 1 ║ 54 ║ 1 ║ Note on tablet. ║ 42:01.8 ║ Jason ║ Turan ║ 2016-12-05T13:36:34 ║ Historian Timestamp ║ 2016-12-05 13:36:34.0000000 +00:00 ║
║ 1 ║ 55 ║ 1 ║ testnotes ║ 47:37.7 ║ Desiree ║ Teter ║ 2016-12-07T15:13:29 ║ Historian Timestamp ║ 2016-12-07 15:13:29.0000000 +00:00 ║
║ 4 ║ 56 ║ 1 ║ notes ║ 09:16.4 ║ Desiree ║ Teter ║ 2016-12-08T14:00:56 ║ Historian Timestamp ║ 2016-12-08 14:00:56.0000000 +00:00 ║
║ 4 ║ 56 ║ 1 ║ notes 2 ║ 09:39.5 ║ Desiree ║ Teter ║ 2016-12-08T14:00:56 ║ Historian Timestamp ║ 2016-12-08 14:00:56.0000000 +00:00 ║
║ 4 ║ 57 ║ 1 ║ ? ║ 36:19.2 ║ Desiree ║ Teter ║ 2016-12-08T14:00:56 ║ Historian Timestamp ║ 2016-12-08 14:00:56.0000000 +00:00 ║
║ 4 ║ 59 ║ 1 ║ testnotes sdfsdf ║ 29:42.1 ║ Desiree ║ Teter ║ 2016-12-08T14:00:56-06:00 ║ Historian Timestamp ║ 2016-12-08 14:00:56.0000000 -06:00 ║
╚═══════════╩═══════════╩═══════════════╩══════════════════╩═══════════════════╩═══════════╩══════════╩═══════════════════════════╩═════════════════════╩════════════════════════════════════╝
然而,当我在CTE Column" HistorianTimestamp"上添加过滤器时。我收到以下错误。
Msg 241,Level 16,State 1,Line 1 从字符串转换日期和/或时间时转换失败。
WITH LogbookSourceObjects AS (
SELECT CAST(obj.NAME AS INT) as LogbookId, ObjectId
FROM PISourceObject obj
JOIN PISource s ON s.SourceID = obj.SourceId
WHERE s.Name ='DEDR' AND ISNUMERIC(obj.NAME) = 1
),
Comments AS (
SELECT lso.LogbookId,
c.CommentId,
c.CommentTypeId,
cd.Comment,
cd.CommentDetailTime,
u.FirstName,
u.LastName,
cp.ParameterValue,
p.Name,
CONVERT(DATETIMEOFFSET, cp.ParameterValue) AS HistorianTimestamp
FROM LogbookSourceObjects lso
JOIN PIComment c ON c.ObjectId = lso.ObjectId
JOIN PICommentDetail cd ON cd.CommentId = c.CommentId
JOIN PICommentType ct ON ct.CommentTypeId = c.CommentTypeId
JOIN PICommentParameter cp on cp.CommentId = c.CommentId
JOIN PIParameter p on cp.ParameterId = p.ParameterId
JOIN PIUser u on u.UserId = cd.UserId
WHERE p.Name ='Historian Timestamp')
SELECT * FROM COMMENTS
WHERE HistorianTimestamp > CONVERT(DATETIMEOFFSET, '2016-11-29T00:00:00-06:00') AND HistorianTimestamp < CONVERT(DATETIMEOFFSET, '2016-11-30T00:00:00-06:00')
我认为这可能是由于执行引擎决定在where子句之前执行select语句。这不是错的吗?执行引擎是否应该遵守语句执行顺序? IE在选择之前应用where子句。如果不是,我怎么能重写声明?
答案 0 :(得分:0)
首先,每当你有:
SELECT * FROM <someCTE>
这意味着你有太多的CTE恕我直言。
您可以像这样简化查询:
WITH LogbookSourceObjects AS (
SELECT CAST(obj.NAME AS INT) as LogbookId, ObjectId
FROM PISourceObject obj
JOIN PISource s ON s.SourceID = obj.SourceId
WHERE s.Name ='DEDR' AND ISNUMERIC(obj.NAME) = 1
)
SELECT lso.LogbookId,
c.CommentId,
c.CommentTypeId,
cd.Comment,
cd.CommentDetailTime,
u.FirstName,
u.LastName,
cp.ParameterValue,
p.Name,
CONVERT(DATETIMEOFFSET, cp.ParameterValue) AS HistorianTimestamp
FROM LogbookSourceObjects lso
JOIN PIComment c ON c.ObjectId = lso.ObjectId
JOIN PICommentDetail cd ON cd.CommentId = c.CommentId
JOIN PICommentType ct ON ct.CommentTypeId = c.CommentTypeId
JOIN PICommentParameter cp on cp.CommentId = c.CommentId
JOIN PIParameter p on cp.ParameterId = p.ParameterId
JOIN PIUser u on u.UserId = cd.UserId
WHERE p.Name ='Historian Timestamp'
AND CONVERT(DATETIMEOFFSET, cp.ParameterValue) > CONVERT(DATETIMEOFFSET, '2016-11-29T00:00:00-06:00')
AND CONVERT(DATETIMEOFFSET, cp.ParameterValue) < CONVERT(DATETIMEOFFSET, '2016-11-30T00:00:00-06:00');
这几乎肯定会失败但会使故障排除更容易一些。然后你可以尝试(从头顶开始):
AND ISDATE(CONVERT(DATETIMEOFFSET, cp.ParameterValue)) = 1
或许......
AND TRY_CONVERT(DATETIMEOFFSET, cp.ParameterValue) > CONVERT(DATETIMEOFFSET, '2016-11-29T00:00:00-06:00')
AND TRY_CONVERT(DATETIMEOFFSET, cp.ParameterValue) < CONVERT(DATETIMEOFFSET, '2016-11-30T00:00:00-06:00');
只是一些值得思考的东西。