我知道计数(*( - 将返回所有行的总计数,包括nulls。计数(colname( - 将返回所有colname不为null的行的总数。
今天,我的大学之一在SQL中遇到了Count((问题。应用一些日期过滤器后,他试图从视图中获取行数。
查看返回数据结构
[Year] VARCHAR(4)
,[Month] VARCHAR(4)
,AType VARCHAR(20)
,PActualsID INT
,EID VARCHAR(12)
,CID INT
,CGId INT
,EMargin NUMERIC(17,3)
,Period DATETIME
,PLID INT
,PCID INT
,PSID INT
,VPID INT
,VSID INT
,STID INT
查询1
SELECT * from vw_ActualAllocation_New
where EntityId = '442105' and
Period >= '01-Jan-2017' AND Period < '01-Jan-2018'
这返回94个记录。
查询2
SELECT Count(*) from vw_ActualAllocation_New
where EID = '442105' and
Period >= '01-Jan-2017' AND Period < '01-Jan-2018'
这返回错误
msg 241,级别16,状态1,第1行转换时失败 来自字符字符串的日期和/或时间。
查询3
SELECT Count(EMargin) from vw_ActualAllocation_New
where EID = '442105' and
Period >= '01-Jan-2017' AND Period < '01-Jan-2018'
这使我算作94。
请注意,Emargin是数字数据类型,也是所有其他类型 例如int和varchar返回相同的错误。
请分享您对这两种行为之间区别的想法。
SQL Server环境:Microsoft SQL Server 2012(构建7601:服务包1((HyperVisor(
更新 - 查看代码
CREATE VIEW [dbo].[vw_ActualAllocation_New]
SELECT D.Year, D.Month, A.AType, A.PAID, D.EntityID, D.CustomerID
,B.CGId, SUM(A.EBITRMargin) AS EBITRMargin
,CONVERT(DATETIME,D.Month + '-01-' + D.Year) AS Period, D.PLID, D.PCID
,D.PSID, D.VPID, D.VSID,D.STID
FROM dbo.AAllocations AS A
INNER JOIN dbo.PActuals AS D ON D.PActualsID = A.PActualsID AND D.Active = 1
INNER JOIN dbo.Customer AS B ON D.CustomerID = B.CustomerID AND D.EntityID =
B.EntityID
INNER JOIN dbo.AStatus AS C ON A.ASID = C.ASID
WHERE (A.Active = 1) AND (C.Active = 1) AND (C.Reference = 'Actuals') AND
(C.Status = 1)
GROUP BY D.Year, D.Month, A.AType, A.PAID, D.EntityID, D.CustomerID, B.CGId,
D.PLID, D.PCID, D.PSID, D.VPID, D.VSID, D.STID
结论更新
得出的结论是 gordon 的建议,如果您觉得自己可能有其他想法,请在此处发布另外,我尝试将数据从视图中使用,换成一个新表格,其工作正常。问题直接从视图访问时发生。视图的生成发生在大量数据中,并且由于其规模巨大和隐私协议而无法在此处发布。感谢您了解我的局限性并帮助我
问题的最有可能的原因是该行的代码:
CONVERT(DATETIME, D.Month + '-01-' + D.Year) AS Period
在SQL Server中,您绝对不应从字符串到日期使用CONVERT()
,而无需指定格式或使用标准格式(yyyymmdd是SQL Server首选的,但我认为Yyyyy-mm-dd也可以接受(。p>在SQL Server的较旧版本中,您可以执行:
CONVERT(DATE, d.Year + RIGHT('00' + D.Month, 2) + '01') as period
这种转换将永远工作。在较新版本中,使用datefromparts()
:
DATEFROMPARTS(d.Year, d.Month, 1) as Period
为什么会发生这种情况?我推测日期格式被解释为DD-MM-Yyyy而不是MM-DD-Yyyy。换句话说,您认为2月1日的是1月2日。
此外,实体" 442105"的周期值都转换为合理的日期。WHERE
子句滤除了不良值。问题在于其他实体和问题,正如达米安指出的那样,是在执行引擎中评估值的地方。