好的,所以这有点难以解释,基本上下面的代码是比较发货日期列与其他3个日期列,然后为每个日期列计算准时%。我将在代码下方解释确切的问题:
SELECT
CAST(o.OrderNo AS INT) AS [OrderNo],
o.CustCode,
CASE
WHEN d2.[Shipment Total] IS NULL THEN o.OrderTotal
ELSE d2.[Shipment Total]
END AS [OrderTotal],
CAST(SUBSTRING(o.NotesToCust, CHARINDEX('ISD',o.NotesToCust)+4, 8) AS DATE) AS [ISD],
CAST(o.User_Date1 AS DATE) AS [3 Week Ack Date],
CAST(o.User_Date2 AS DATE) AS [1 Week Ack Date],
CAST(d.ShipDate AS DATE) AS [Ship Date],
CASE
WHEN CAST(d.Notes2Cust AS VARCHAR(MAX)) LIKE '%partial%' THEN 'Partial Shipment'
WHEN CAST(d.Notes2Cust AS VARCHAR(MAX)) LIKE '%complete%' THEN 'Shipped Complete'
END AS [Shipment Notes],
CAST(CASE
WHEN o.User_Number3 <> '0'
THEN o.User_Number3
ELSE NULL
END AS INT) AS [Late Reason Code(s)],
(CAST(SUM(CASE
WHEN CAST(d.ShipDate AS DATE) <= CAST(SUBSTRING(o.NotesToCust, CHARINDEX('ISD',o.NotesToCust)+4, 8) AS DATE)
AND CAST(d.Notes2Cust AS VARCHAR(MAX)) NOT LIKE '%partial%'
AND (CAST(o.User_Number3 AS INT) IS NULL
OR CAST(o.User_Number3 AS INT) = 0
OR CAST(o.User_Number3 AS INT) = 3
OR CAST(o.User_Number3 AS INT) = 4
OR CAST(o.User_Number3 AS INT) = 5
OR CAST(o.User_Number3 AS INT) = 6
OR CAST(o.User_Number3 AS INT) = 7
OR CAST(o.User_Number3 AS INT) = 8
OR CAST(o.User_Number3 AS INT) = 9)
AND o.CustCode NOT LIKE '%Euroline%'
AND o.CustCode NOT LIKE 'Savi B%'
THEN 1
ELSE 0
END) OVER(PARTITION BY MONTH(d.ShipDate)) AS FLOAT))/
NULLIF((CAST(SUM(CASE
WHEN CAST(d.Notes2Cust AS VARCHAR(MAX)) NOT LIKE '%partial%'
AND (CAST(o.User_Number3 AS INT) IS NULL
OR CAST(o.User_Number3 AS INT) = 0
OR CAST(o.User_Number3 AS INT) = 3
OR CAST(o.User_Number3 AS INT) = 4
OR CAST(o.User_Number3 AS INT) = 5
OR CAST(o.User_Number3 AS INT) = 6
OR CAST(o.User_Number3 AS INT) = 7
OR CAST(o.User_Number3 AS INT) = 8
OR CAST(o.User_Number3 AS INT) = 9)
AND o.CustCode NOT LIKE '%Euroline%'
AND o.CustCode NOT LIKE 'Savi B%'
THEN 1
ELSE 0
END) OVER(PARTITION BY MONTH(d.ShipDate)) AS FLOAT)),0) AS [ISD On-Time %],
(CAST(SUM(CASE
WHEN CAST(d.ShipDate AS DATE) <= CAST(o.User_Date1 AS DATE)
AND CAST(d.Notes2Cust AS VARCHAR(MAX)) NOT LIKE '%partial%'
AND (CAST(o.User_Number3 AS INT) IS NULL
OR CAST(o.User_Number3 AS INT) = 0
OR CAST(o.User_Number3 AS INT) = 3
OR CAST(o.User_Number3 AS INT) = 4
OR CAST(o.User_Number3 AS INT) = 5
OR CAST(o.User_Number3 AS INT) = 6
OR CAST(o.User_Number3 AS INT) = 7
OR CAST(o.User_Number3 AS INT) = 8
OR CAST(o.User_Number3 AS INT) = 9)
AND o.CustCode NOT LIKE '%Euroline%'
AND o.CustCode NOT LIKE 'Savi B%'
THEN 1
ELSE 0
END) OVER(PARTITION BY MONTH(d.ShipDate)) AS FLOAT))/
NULLIF((CAST(SUM(CASE
WHEN CAST(d.Notes2Cust AS VARCHAR(MAX)) NOT LIKE '%partial%'
AND (CAST(o.User_Number3 AS INT) IS NULL
OR CAST(o.User_Number3 AS INT) = 0
OR CAST(o.User_Number3 AS INT) = 3
OR CAST(o.User_Number3 AS INT) = 4
OR CAST(o.User_Number3 AS INT) = 5
OR CAST(o.User_Number3 AS INT) = 6
OR CAST(o.User_Number3 AS INT) = 7
OR CAST(o.User_Number3 AS INT) = 8
OR CAST(o.User_Number3 AS INT) = 9)
AND o.CustCode NOT LIKE '%Euroline%'
AND o.CustCode NOT LIKE 'Savi B%'
THEN 1
ELSE 0
END) OVER(PARTITION BY MONTH(d.ShipDate)) AS FLOAT)),0) AS [3 Week On-Time %],
(CAST(SUM(CASE
WHEN CAST(d.ShipDate AS DATE) <= CAST(o.User_Date2 AS DATE)
AND CAST(d.Notes2Cust AS VARCHAR(MAX)) NOT LIKE '%partial%'
AND (CAST(o.User_Number3 AS INT) IS NULL
OR CAST(o.User_Number3 AS INT) = 0
OR CAST(o.User_Number3 AS INT) = 3
OR CAST(o.User_Number3 AS INT) = 4
OR CAST(o.User_Number3 AS INT) = 5
OR CAST(o.User_Number3 AS INT) = 6
OR CAST(o.User_Number3 AS INT) = 7
OR CAST(o.User_Number3 AS INT) = 8
OR CAST(o.User_Number3 AS INT) = 9)
AND o.CustCode NOT LIKE '%Euroline%'
AND o.CustCode NOT LIKE 'Savi B%'
THEN 1
ELSE 0
END) OVER(PARTITION BY MONTH(d.ShipDate)) AS FLOAT))/
NULLIF((CAST(SUM(CASE
WHEN CAST(d.Notes2Cust AS VARCHAR(MAX)) NOT LIKE '%partial%'
AND (CAST(o.User_Number3 AS INT) IS NULL
OR CAST(o.User_Number3 AS INT) = 0
OR CAST(o.User_Number3 AS INT) = 3
OR CAST(o.User_Number3 AS INT) = 4
OR CAST(o.User_Number3 AS INT) = 5
OR CAST(o.User_Number3 AS INT) = 6
OR CAST(o.User_Number3 AS INT) = 7
OR CAST(o.User_Number3 AS INT) = 8
OR CAST(o.User_Number3 AS INT) = 9)
AND o.CustCode NOT LIKE '%Euroline%'
AND o.CustCode NOT LIKE 'Savi B%'
THEN 1
ELSE 0
END) OVER(PARTITION BY MONTH(d.ShipDate)) AS FLOAT)),0) AS [1 Week On-Time %]
FROM Orders o
JOIN OrderDet od ON o.OrderNo = od.OrderNo
JOIN TimeTicketDet t ON od.JobNo = t.JobNo
LEFT JOIN DelTicket d ON o.OrderNo = d.OrderNo AND d.Notes2Cust NOT LIKE '%rework%'
LEFT JOIN
(
SELECT
od1.OrderNo AS [OrderNo],
d1.ShipDate AS [ShipDate],
d1.DelTicketNo AS [DelTicketNo],
SUM(od1.UnitPrice*od1.QtyOrdered) AS [Shipment Total]
FROM OrderDet od1
JOIN DelTicketDet dt1 ON od1.JobNo = dt1.JobNo
JOIN DelTicket d1 ON dt1.DelTicketNo = d1.DelTicketNo
GROUP BY od1.OrderNo, d1.ShipDate, d1.DelTicketNo
) AS [d2] ON d.OrderNo = d2.OrderNo AND d.ShipDate = d2.ShipDate
WHERE CONVERT(VARCHAR(MAX), o.User_Memo1) IS NOT NULL
AND SUBSTRING(o.User_Memo1, 1, 3) = 'Cut'
AND CAST(d.ShipDate AS DATE) BETWEEN '20180101' AND '20180331'
AND o.CustCode NOT LIKE '%Euroline%'
AND o.CustCode NOT LIKE 'Savi B%'
GROUP BY
o.OrderNo, o.CustCode, d2.[Shipment Total], o.OrderTotal, CAST(SUBSTRING(o.NotesToCust, CHARINDEX('ISD',o.NotesToCust)+4, 8) AS DATE), CAST(o.User_Date1 AS DATE), CAST(o.User_Date2 AS DATE),
CAST(d.ShipDate AS DATE), d.ShipDate, o.User_Number3, CAST(d.Notes2Cust AS VARCHAR(MAX))
ORDER BY CAST(d.ShipDate AS DATE) DESC
好的,因此此查询返回以下错误: “从字符串转换日期和/或时间时转换失败”
好的,然后我尝试更改此行:
AND CAST(d.ShipDate AS DATE) BETWEEN '20180101' AND '20180331'
介于20180101和20180228之间,并且有效!好的,那么我发现转换问题出在3月1日至3月31日之间。所以然后我在20180301和20180331之间更改了同一行,说这不起作用,但是确实有效,这让我头疼。本质上,如果我将相同的代码与一个代码块(从20180101到20180228)和第二个代码块(用于捕获3月的记录)结合在一起,那么它将很好地工作。但是,如果我在1月1日到3月31日之间去了,那是行不通的。什么鬼?
我刚刚检查了要转换的每个字段,应该没有任何错误,我转换为日期的所有内容都应该100%正常工作。我真的对如何进行此操作感到茫然。联盟并不是一个真正的选择,因为我需要25个联盟来捕获我在几年内需要的所有数据。此外,当代码应正常执行时,不必将其用作解决方法
答案 0 :(得分:2)
没有足够的信息可以给您确定的答案,但这是您找到它的方法。
发生错误是因为您尝试将字符串强制转换为日期而该字符串不是有效日期。代码段CAST(SUBSTRING(o.NotesToCust, CHARINDEX('ISD',o.NotesToCust)+4, 8) AS DATE)
显然是将字符串转换为日期,但是我不知道它可能在查询中的其他地方发生,因为我不知道您的哪些列是字符串,哪些列是date /日期时间。
但是您可以做的是,在查询中将varchar强制转换为日期的任何地方,都可以将强制类型更改为TRY_CAST(),并查找TRY_CAST()导致返回NULL的行。然后,您将找到导致错误的行。