这是我用来获取年龄在25到34岁之间的所有用户的SQL Server 2012查询的精简版本。在我的表中,
WITH AgeCTE AS
(
SELECT
CASE
WHEN DATEADD(yy, DATEDIFF(yy, CONVERT(DATETIME, Feedback), FeedbackDate), CONVERT(DATETIME, Feedback)) < FeedbackDate
THEN DATEDIFF(yy, CONVERT(DATETIME, Feedback), FeedbackDate)
ELSE DATEDIFF(yy, CONVERT(DATETIME, Feedback), FeedbackDate) - 1
END AS Age
FROM FeedbackTable
)
SELECT COUNT(*) AS [25To34] FROM AgeCTE WHERE (Age >= 25) AND (Age <= 34)
执行此查询时,我收到以下错误:
Conversion failed when converting date and/or time from character string.
此外,当我尝试执行内部查询时,它会成功执行,这表明在执行内部查询之前,日期的格式不是问题。
例如,当我执行以下查询时:
SELECT
CASE
WHEN DATEADD(yy, DATEDIFF(yy, CONVERT(DATETIME, Feedback), FeedbackDate), CONVERT(DATETIME, Feedback)) < FeedbackDate
THEN DATEDIFF(yy, CONVERT(DATETIME, Feedback), FeedbackDate)
ELSE DATEDIFF(yy, CONVERT(DATETIME, Feedback), FeedbackDate) - 1
END AS Age
FROM FeedbackTable
我得到一个输出:
年龄
23 33 35 8 等...
如果省略最后一个WHERE子句,即使是CTE的整个查询也能正常工作。具体来说,如果我删除部分
WHERE (Age >= 25) AND (Age <= 34)
并执行以下查询:
WITH AgeCTE AS
(
SELECT
CASE
WHEN DATEADD(yy, DATEDIFF(yy, CONVERT(DATETIME, Feedback), FeedbackDate), CONVERT(DATETIME, Feedback)) < FeedbackDate
THEN DATEDIFF(yy, CONVERT(DATETIME, Feedback), FeedbackDate)
ELSE DATEDIFF(yy, CONVERT(DATETIME, Feedback), FeedbackDate) - 1
END AS Age
FROM FeedbackTable
)
SELECT COUNT(*) AS [25To34] FROM AgeCTE
我得到以下输出:
25To34
9
我无法理解WHERE子句的问题。我在互联网上的某处读到它可能是短路的,但是,我无法弄清楚如何。任何帮助将不胜感激。
答案 0 :(得分:0)
首先:以字符串格式存储日期总是一个坏主意......
其次:您的格式dd-mm-yyyy
- 甚至更糟 - 文化特定。在没有第三个参数的情况下使用CONVERT()
是赌博。这是否有效取决于您的系统设置。
首次尝试时,我会添加相应的代码Find details here:
CONVERT(DATETIME, Feedback, 105)
如果仍然遇到问题,可以使用此方法(SQL-Server 2012 +)
SELECT *
FROM YourTable
WHERE TRY_CONVERT(DATETIME,Feedback) IS NULL
TRY_CONVERT
是一个非常新的函数,如果转换失败则返回NULL。
答案 1 :(得分:0)
我相信您可以使用ISDATE()
检查并查看是否可以转换该值。如果没有,那么您可以返回零,并且该行将从您的查询中排除。
WITH AgeCTE AS
(
SELECT
CASE
WHEN DATEADD(yy, DATEDIFF(yy, CONVERT(DATETIME, Feedback), FeedbackDate), CONVERT(DATETIME, Feedback)) < FeedbackDate
THEN DATEDIFF(yy, CONVERT(DATETIME, Feedback), FeedbackDate)
ELSE
CASE
WHEN ISDATE(Feedback) = 1
THEN DATEDIFF(yy, CONVERT(DATETIME, Feedback), FeedbackDate) - 1
ELSE
0
END
END AS Age
FROM FeedbackTable
)
SELECT COUNT(*) AS [25To34]
FROM AgeCTE
WHERE (Age >= 25) AND (Age <= 34)
我会回应@Shnugo所说的内容,你应该在CONVERT
语句中使用隐式格式参数,而不是使用VARCHAR
来存储日期。