我编写了一个存储过程,用于根据表列中的值计算年龄。
这是存储过程:
WITH ages AS
(
SELECT
DATEDIFF(YEAR, CONVERT(datetime, pf.Value, 104), pf.CreatedOn) END as Age
FROM
Fields pf
WHERE
pf.Value IS NOT NULL
)
SELECT
(SELECT COUNT(Age)
FROM ages
WHERE ages.Age > 17 AND ages.Age < 25) AS '18-24',
(SELECT COUNT(Age)
FROM ages
WHERE ages.Age > 24 AND ages.Age < 31) AS 25-30',
(SELECT COUNT(Age)
FROM ages
WHERE ages.Age > 30 AND ages.Age < 36) AS '31-35',
(SELECT COUNT(Age)
FROM ages
WHERE ages.Age > 35) AS '> 35'
在此列(值)中,生日存储为字符串值,格式如下:02.10.1987 00:00:00(DD.MM.YYY HH:mm:ss)。
在这个Fields
表格中,我有3500行。
数据如下所示:
02.10.1987 00:00:00
29.07.1967 12:33:11
02.10.1987 00:00:00
15.11.1959 00:00:00
07.11.1975 00:00:00
当我运行这样的过程时,SQL服务器返回以下错误:
从字符串
转换日期和/或时间时转换失败
如果我将Top 100000放在存储过程中,则执行程序正常,如下所示:
WITH ages AS
(
SELECT TOP 100000 datediff(year, CONVERT(datetime, pf.Value, 104), pf.CreatedOn)
END as Age
FROM Fields pf
where pf.Value is not null
)
SELECT (select count(Age) FROM ages where ages.Age>17 and ages.Age<25) as '18-24',
(select count(Age) FROM ages where ages.Age>24 and ages.Age<31) as '25-30',
(select count(Age) FROM ages where ages.Age>30 and ages.Age<36) as '31-35',
(select count(Age) FROM ages where ages.Age>35) as '>35'
正如我所写,我只有3500行。
我的所有数据格式都正确,存储过程的所有非空值。
有人知道为什么会这样吗?为什么它使用Top插入,但不是没有它?
具有内存分配的东西是SQL Server做的吗?
答案 0 :(得分:0)
这些都是长镜头,但也许可以尝试:
完全有可能是TOP 10000&amp;直接SELECT生成不同的执行计划,但我仍然不明白为什么会影响数据。
你确定没有其他事情发生吗?查询的两个连接都使用相同的用户?两个连接的区域设置是否相同?
答案 1 :(得分:0)
尝试将CONVERT(datetime,pf.Value,104)更改为Cast(pf.Value as DateTime)或 如果你真的不关心日期的时间戳部分,请加注(pf.Value as Date)。
另外,如果pf.CreatedOn的类型是varchar,那就用它来做同样的事情。
WITH ages AS
(
SELECT
DATEDIFF(YEAR, cast(pf.Value AS DateTime), CAST(pf.CreatedOn AS DATETIME)) END as Age
FROM
Fields pf
WHERE
pf.Value IS NOT NULL
)
对不起......我没有意识到你的约会时间已经过了#34;你不是来自这里的,是吗?&#34;格式。尝试这种不太吸引人的解决方案。
--TestData
DECLARE @x NVARCHAR(MAX) = '29.11.1956 00:00:00'
DECLARE @x NVARCHAR(MAX) = '2.1.1956 00:00:00'
--Solution
select
-- Monthpart dd.mm.yyy
SUBSTRING(@x,
CHARINDEX('.', @x) + 1 ,
CHARINDEX('.',@x,CHARINDEX('.', @x) + 1 )- CHARINDEX('.', @x) -1) + '/'
--DayPart dd.mm.yyy
+ SUBSTRING(@x, 1, CHARINDEX('.', @X) - 1) + '/'
--YearPart
+ RIGHT(LEFT (@x, CHARINDEX(' ',@x) -1),4)