我在VS 2017中创建了一个简单的视图。这是:
CREATE VIEW [dbo].[ApplicantStat]
AS SELECT ISNULL(CONVERT(VARCHAR(50), NEWID()), '') AS ID,
ISNULL(AVG(ApplicationTime), 0) AS 'AvgApplicationTime',
ISNULL(AVG(ResponseTime), 0) AS 'AvgResponseTime',
ISNULL(CAST(COUNT(CASE WHEN [IsAccepted] = 1 THEN 1 END) / COUNT(CASE WHEN [IsValid] = 1 THEN 1 END) AS float), 0) AS 'PctAccepted'
FROM [Application]
WHERE CreatedOn BETWEEN CAST(GETDATE()-30 AS date) AND CAST(GETDATE()-1 AS date)
如您所见,它获取2个日期之间的数据并进行一些简单的聚合。
演员的想法是我想忽略时间并且无论如何都要获得日期范围的所有内容 - 所以截至今天,3月15日,我会在3月14日00:00:00 - 23之间取出所有内容: 59:59和29天前。
这不会发生 - 它会拾取3行(第13行) - 它应该拾取所有5行。是的,我的系统日期目前是15/03/2018 14:44(英国时间)。
这是表格和数据:
CREATE TABLE [dbo].[Application] (
[Id] INT NOT NULL,
[ApplicantId] INT NOT NULL,
[LoanAmount] INT NOT NULL,
[LoanTerm] SMALLINT NOT NULL,
[EmailAddress] VARCHAR (254) NOT NULL,
[MobilePhone] VARCHAR (11) NOT NULL,
[House] VARCHAR (25) NOT NULL,
[Street] VARCHAR (50) NOT NULL,
[TownCity] VARCHAR (50) NOT NULL,
[Postcode] VARCHAR (7) NOT NULL,
[IpAddress] VARCHAR (39) NOT NULL,
[IsValid] BIT NOT NULL,
[IsAccepted] BIT NOT NULL,
[Commission] DECIMAL (9, 2) NOT NULL,
[Processors] VARCHAR (500) NOT NULL,
[ResponseTime] SMALLINT NOT NULL,
[ApplicationTime] SMALLINT NOT NULL,
[CreatedOn] DATETIME NOT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
INSERT INTO [dbo].[Application] ([Id], [ApplicantId], [LoanAmount], [LoanTerm], [EmailAddress], [MobilePhone], [House], [Street], [TownCity], [Postcode], [IpAddress], [IsValid], [IsAccepted], [Commission], [Processors], [ResponseTime], [ApplicationTime], [CreatedOn]) VALUES (1, 1, 300, 3, N'john.doe@tmail.com', N'07957000000', N'1', N'Acacia Avenue', N'Suburbia', N'SB1 2RB', N'100.100.100.100', 1, 1, CAST(3.20 AS Decimal(9, 2)), N'1,2,3,4,5', 90, 600, N'2018-03-13 08:00:00')
INSERT INTO [dbo].[Application] ([Id], [ApplicantId], [LoanAmount], [LoanTerm], [EmailAddress], [MobilePhone], [House], [Street], [TownCity], [Postcode], [IpAddress], [IsValid], [IsAccepted], [Commission], [Processors], [ResponseTime], [ApplicationTime], [CreatedOn]) VALUES (2, 2, 500, 12, N'a@b.com', N'0', N'1', N'a', N's', N's', N'1', 0, 1, CAST(5.00 AS Decimal(9, 2)), N'1', 60, 300, N'2018-03-14 16:00:00')
INSERT INTO [dbo].[Application] ([Id], [ApplicantId], [LoanAmount], [LoanTerm], [EmailAddress], [MobilePhone], [House], [Street], [TownCity], [Postcode], [IpAddress], [IsValid], [IsAccepted], [Commission], [Processors], [ResponseTime], [ApplicationTime], [CreatedOn]) VALUES (3, 3, 1000, 6, N'a@b.com', N'0', N'1', N'a', N's', N's', N'1', 1, 1, CAST(7.00 AS Decimal(9, 2)), N'1', 75, 360, N'2018-03-13 10:00:00')
INSERT INTO [dbo].[Application] ([Id], [ApplicantId], [LoanAmount], [LoanTerm], [EmailAddress], [MobilePhone], [House], [Street], [TownCity], [Postcode], [IpAddress], [IsValid], [IsAccepted], [Commission], [Processors], [ResponseTime], [ApplicationTime], [CreatedOn]) VALUES (4, 4, 2000, 24, N'a@b.com', N'0', N'1', N'a', N's', N's', N'1', 1, 1, CAST(20.00 AS Decimal(9, 2)), N'1', 30, 365, N'2018-03-14 11:00:00')
INSERT INTO [dbo].[Application] ([Id], [ApplicantId], [LoanAmount], [LoanTerm], [EmailAddress], [MobilePhone], [House], [Street], [TownCity], [Postcode], [IpAddress], [IsValid], [IsAccepted], [Commission], [Processors], [ResponseTime], [ApplicationTime], [CreatedOn]) VALUES (5, 5, 3000, 18, N'a@b.com', N'0', N'1', N'a', N's', N's', N'1', 1, 1, CAST(40.00 AS Decimal(9, 2)), N'1', 45, 330, N'2018-03-13 12:00:00')
答案 0 :(得分:4)
试试这个:
WHERE
CreatedOn >= CAST(GETDATE()-30 AS date) AND
CreatedOn < CAST(GETDATE() AS date)
问题是你在前一天转换为日期。
答案 1 :(得分:3)
您可以CAST
将CreatedOn
字段DATE
移除WHERE CAST(CreatedOn AS DATE) BETWEEN CAST(GETDATE()-30 AS date) AND CAST(GETDATE()-1 AS date)
以删除时间部分,这会妨碍您...
也许
CAST
但是 - SELECT TOP 1000
CreatedOn
,CAST(GETDATE()-30 AS date)
,CAST(GETDATE()-1 AS date)
FROM [Application]
WHERE表达式中的字段可能使其不是SARGable。见here。因此,除非您知道表达式是SARGable,否则请避免在大型或生产环境中使用此解决方案。仅用作测试来优化您的逻辑和选项。 (即使CreatedOn上没有显式索引 - 如果没有明确存在索引,SQL 可能仍然会受到影响,因为SQL会一直构建自己的索引。
总是值得确认它是否是SARGable所以你肯定知道。)
要查看正在发生的事情 - 在SELECT中查看您的值 - 只是为了了解正在运行的内容
例如:
routes.MapRoute("Upload", "Upload/{id}",new { controller = "Upload", action = "Index" });
或查看从数据时间字段here中删除时间值的其他选项 因为你可能想要强制或舍入时间值
答案 2 :(得分:2)
不要试图忽略时间值,只需确保您的搜索字词准确无误。另外,不要盲目地向每列添加ISNULL
之类的内容。花几秒钟思考它是否相关。例如,NEWID()
永远不会向您返回NULL
值。添加这种代码是糟糕的编程,这将导致不太清晰的代码。
以下是我如何编写它来计算时间部分:
CREATE VIEW dbo.ApplicantStat
AS
SELECT
CONVERT(VARCHAR(50), NEWID()) AS ID,
COALESCE(AVG(ApplicationTime), 0) AS AvgApplicationTime,
COALESCE(AVG(ResponseTime), 0) AS AvgResponseTime,
COALESCE(CAST(COUNT(CASE WHEN [IsAccepted] = 1 THEN 1 END) / COUNT(CASE WHEN [IsValid] = 1 THEN 1 END) AS float), 0) AS PctAccepted
FROM
dbo.Application
WHERE
CreatedOn >= DATEADD(DAY, -30, CAST(GETDATE() AS DATE)) AND
CreatedOn < CAST(GETDATE() AS DATE)