SQL - 日期变量未正确解析?

时间:2013-10-21 15:14:03

标签: sql sql-server filter

我正在提取按开始日期和结束日期过滤的发票列表,并进一步按照SQL表格中的发票类型进行过滤。当我指定2013-07-01至2013-09-30的范围时,我预计每个公司收到2张发票。当我在SSMS中使用内置的选择前1000名查询并添加我的日期过滤器时,所有预期发票出现。

以下是我使用的有趣的查询:利用输入的变量:

DECLARE @ReportStart datetime
DECLARE @ReportStop datetime

SET @ReportStart = '2013-07-01'
SET @ReportStop = '2013-09-30'

SELECT Entity_Company.CompanyName,
Reporting_AgreementTypes.Description,
Reporting_Invoices.InvoiceAmount,
ISNULL(Reporting_ProductCost.ProductCost,0),
(Reporting_Invoices.InvoiceAmount - ISNULL(Reporting_ProductCost.ProductCost,0)),
(Reporting_AgreementTypes.Description + Entity_Company.CompanyName),
Reporting_Invoices.InvoiceDate
FROM Reporting_Invoices
JOIN Entity_Company ON Entity_Company.ClientID = Reporting_Invoices.ClientID
LEFT JOIN Reporting_ProductCost ON Reporting_ProductCost.InvoiceNumber =Reporting_Invoices.InvoiceNumber
JOIN Reporting_AgreementTypes ON Reporting_AgreementTypes.AgreementTypeID = Reporting_Invoices.AgreementTypeID
WHERE Reporting_Invoices.AgreementTypeID = (SELECT AgreementTypeID FROM Reporting_AgreementTypes WHERE Description = 'Resold Services')
AND Reporting_Invoices.InvoiceDate >= @ReportStart AND Reporting_Invoices.InvoiceDate <= @ReportStop

ORDER BY CompanyName,InvoiceDate

以上只返回每家公司的2张发票。当我通过SSMS运行更基本的查询时,我按预期得到3,看起来像:

SELECT TOP 1000 [InvoiceID]
      ,[AgreementID]
      ,[AgreementTypeID]
      ,[InvoiceDate]
      ,[Comment]
      ,[InvoiceAmount]
      ,[InvoiceNumber]
      ,[TicketID]
      ,Entity_Company.CompanyName
  FROM Reporting_Invoices
  JOIN Entity_Company ON Entity_Company.ClientID = Reporting_Invoices.ClientID
  WHERE Entity_Company.ClientID = '9' AND 
  AgreementTypeID = (SELECT AgreementTypeID FROM Reporting_AgreementTypes WHERE Description = 'Resold Services')

  AND Reporting_Invoices.InvoiceDate >= '2013-07-01' AND Reporting_Invoices.InvoiceDate <= '2013-09-30'

  ORDER BY InvoiceDate DESC

我尝试剥离第一个查询,只在原始发票表中包含客户ID,发票日期,没有其他内容。仍然只能得到2张发票而不是预期的3.我还尝试手动输入日期而不是@变量,结果相同。我确认InvoiceDate被定义为表中的日期时间。我已经尝试让所有JOIN成为一个完全加入以查看是否有任何隐藏,但没有任何变化。下面是我如何删除原始查询以保持所有其他表不在混合中,但我仍然只为每个客户端ID而不是3(我手动输入类型过滤器的ID)只收到2个发票:

--DECLARE @ReportStart datetime
--DECLARE @ReportStop datetime

--SET @ReportStart = '2013-07-01'
--SET @ReportStop = '2013-09-30'

SELECT --Entity_Company.CompanyName,
--Reporting_AgreementTypes.Description,
Reporting_Invoices.ClientID,
Reporting_Invoices.InvoiceAmount,
--ISNULL(Reporting_ProductCost.ProductCost,0),
--(Reporting_Invoices.InvoiceAmount - ISNULL(Reporting_ProductCost.ProductCost,0)),
--(Reporting_AgreementTypes.Description + Entity_Company.CompanyName),
Reporting_Invoices.InvoiceDate
FROM Reporting_Invoices
--JOIN Entity_Company ON Entity_Company.ClientID = Reporting_Invoices.ClientID
--LEFT JOIN Reporting_ProductCost ON Reporting_ProductCost.InvoiceNumber = Reporting_Invoices.InvoiceNumber
--JOIN Reporting_AgreementTypes ON Reporting_AgreementTypes.AgreementTypeID = Reporting_Invoices.AgreementTypeID
WHERE Reporting_Invoices.AgreementTypeID = '22'-- (SELECT AgreementTypeID FROM Reporting_AgreementTypes WHERE Description = 'Resold Services')
AND Reporting_Invoices.InvoiceDate >= '2013-07-01' AND Reporting_Invoices.InvoiceDate <= '2013-09-30'

ORDER BY ClientID,InvoiceDate

这让我觉得非常奇怪,因为它与SSMS生成的查询几乎完全相同,返回正确的结果。我在俯瞰什么?

更新

我进一步完善了我的测试查询&#34;每个公司只返回2张发票,以帮助排除故障。以下是来自相应表格的1家公司的查询和相关数据子集:

SELECT Reporting_Invoices.ClientID,
Reporting_AgreementTypes.Description,
Reporting_Invoices.InvoiceAmount,
Reporting_Invoices.InvoiceDate
FROM Reporting_Invoices
JOIN Reporting_AgreementTypes ON Reporting_AgreementTypes.AgreementTypeID = Reporting_Invoices.AgreementTypeID
WHERE Reporting_Invoices.AgreementTypeID = (SELECT AgreementTypeID FROM Reporting_AgreementTypes WHERE Description = 'Resold Services')
AND Reporting_Invoices.InvoiceDate >= '2013-07-01T00:00:00' AND Reporting_Invoices.InvoiceDate <= '2013-09-30T00:00:00'

ORDER BY Reporting_Invoices.ClientID,InvoiceDate

以上只返回2张发票。以下是相关的表格数据:

Relevant data from Reporting_AgreementTypes         
AgreementTypeID Description     
22              Resold Services     

Relevant data from Reporting_Invoices           
InvoiceID   ClientID    AgreementID AgreementTypeID     InvoiceDate
16111     9         757         22                  2013-09-30 00:00:00.000
15790     9         757         22                  2013-08-30 00:00:00.000
15517     9         757         22                  2013-07-31 00:00:00.000

Actual results from my new modified query           
ClientID    Description InvoiceAmount   InvoiceDate
9           Resold Services 3513.79         7/31/13 00:00:00
9        Resold Services    3570.49         8/30/13 00:00:00

2 个答案:

答案 0 :(得分:0)

要检查的事项:

  • “2013-09-30”上缺少发票吗?
  • InvoiceDate实际上是带有时间元素的日期时间吗?

如果您要比较日期时间,则除非指定,否则时间为00:00,这将排除该日期的大部分时间。如果你想包含它,那么你可以使用

 < '2013-10-01'

 convert(date, InvoiceDate) <= '2013-09-30'

答案 1 :(得分:0)

检查1:您确定要查看同一个数据库吗?检查SSMS中的右下角。


检查2 :在不同的dateformatlanguage选项下,日期表示不同的内容。例如,日期2013-01-02表示法国2月1日:

set language french
select cast('2010-02-01' as datetime)
--> 2010-01-02 00:00:00.000
set language us_english
select cast('2010-02-01' as datetime)
--> 2010-02-01 00:00:00.000
set dateformat ydm
select cast('2010-02-01' as datetime)
--> 2010-01-02 00:00:00.000

您可以使用以下方式显示当前日期格式选项:

select  s.date_format
,       s.language 
from    sys.dm_exec_sessions s
where   s.session_id = @@spid

将上述查询置于其他两个查询之上并比较结果。


检查3:打开的交易的效果仅在其自己的会话中可见。因此,请检查是否有任何未结交易。你可以这样做:

dbcc opentran

检查4 :该列的类型与您与之比较的类型不同吗?如果是这样,SQL Server将使用lower precedence将数据类型转换为具有更高优先级的数据类型。

以下是一个例子:

create table t1 (dt date);
insert t1 values ('2010-01-01');
select * from t1 where dt = '1 Jan 2010'

这将返回一行,因为date的优先级高于varchar。因此'1 Jan 2010'会转换为date。如果情况相反,则'2010-01-01'与匹配'1 Jan 2010'不匹配。