SQL Server当前日期与特定日期进行比较

时间:2017-08-08 12:14:25

标签: sql-server

我有一张桌子,这是dbo.Invoice。我现在的查询现在能够选择没有“Mvt_Type”='122'发票的“SalesRef”。但是,我需要使用PostDate字段扩展我的查询。

我的问题是当前查询仍显示SalesRef,其今日(2017年8月8日)的Postdate“Mvt_Type”=“122”没有发票。我的预期结果是,如果在过期后2天内没有发票,则只能显示。因此,它假设在2017年11月8日或更长时间显示。

表dbo.Invoice

| PO_NUMBER     | TYPE  | MVT_TYPE  | QUANTITY  | SALESREF  | DEBIT     | POSTDATE      |
|-----------    |------ |---------- |---------- |---------- |-------    |------------   |
| 10001001      | GR    | 101       | 1000.00   | 5001      | S         | 2017-01-08    |
| 10001001      | GR    | 101       | 2000.00   | 5002      | S         | 2017-02-08    |
| 10001001      | GR    | 122       | 1000.00   | 5001      | H         | 2017-01-08    |
| 10001001      | INV   | 000       | 1000.00   | 5001      | S         | 2017-01-08    |
| 10001001      | INV   | 000       | 2000.00   | 5002      | S         | 2017-02-08    |
| 10001001      | GR    | 122       | 1500.00   | 5002      | H         | 2017-02-08    |
| 10001001      | INV   | 000       | 1000.00   | 5001      | H         | 2017-01-08    |

以下是我当前的查询:

  SELECT * 
FROM dbo.INVOICE i 
WHERE MVT_TYPE = '122' AND SALESREF IS NOT NULL AND POSTDATE > CONVERT(VARCHAR(10), dateadd(day,2,getdate()),101) 
AND NOT EXISTS (SELECT 1 
FROM dbo.INVOICE 
WHERE DEBIT = 'H' AND  MVT_TYPE = '000' AND SALESREF = i.SALESREF ) 

预期结果与下面相同。但这次需要添加PostDate。

| PO_NUMBER     | TYPE  | MVT_TYPE  | QUANTITY  | SALESREF  | DEBIT     | POSTDATE      |
|-----------    |------ |---------- |---------- |---------- |-------    |------------   |
| 10001001      | GR    | 122       | 1500.00   | 5002      | H         | 2017-02-08    |

3 个答案:

答案 0 :(得分:1)

如果PostDate是DATE或DATETIME,而不是强制转换,您可以使用DATEDIFF函数来获取两个日期之间的日期并进行INT比较:

WHERE DATEDIFF(DAY, PostDate, GETDATE())>2

如果PostDate是varchar,则以OP:

中显示的格式存储
SET LANGUAGE british

SELECT ....
WHERE DATEDIFF(DAY, CAST(PostDate as datetime), GETDATE())>2

编辑:如果PostDate也是VARCHAR数据类型,显然DATEDIFF也可以使用

DECLARE @PostDate VARCHAR(50)

SET @PostDate='08-01-2017'

SELECT DATEDIFF(DAY, @PostDate, GETDATE()) -- GETDATE() is 08-08-2017

-- Returns 7

说到这里,将Dates和Times保持为正确的数据类型是一个好习惯。在您的情况下,如果可能,您可以将数据类型更改为DATE。将加快查找速度

编辑2:请注意,SQL Server使用ISO 8601日期格式,即YYYY-MM-DD,但OP的示例中的日期,即使按照OP参考2017年8月的日期不正确(参考2017年1月和2月)并存储为varchar。为了获得正确的结果,这些结果需要转换为DATE / DATETIME数据类型,或者使用正确的ISO格式重新格式化。

编辑3:在调用DATEDIFF之前,显示将OP的日期格式转换为正确的ISO格式的示例:

SET LANGUAGE british

DECLARE @PostDate VARCHAR(50)

SET @PostDate='2017-01-08'

SELECT DATEDIFF(DAY, CAST(@PostDate AS DATETIME), GETDATE()) -- GETDATE() is 08-08-2017

-- Returns 7

WHERE子句如下:

- 在选择陈述的开头

SET LANGUAGE british

SELECT *
FROM ...
WHERE DATEDIFF(DAY, CAST(PostDate as datetime), GETDATE())>2

答案 1 :(得分:0)

是POSTDATE - 日期列吗?如果不是,那么您要比较字符串,结果与'2017-01-08' > '08/10/2017' ('2' > '0')一样。很可能你只需要施放POSTDATE。参见示例:

select
case
when '2017-01-08'  > CONVERT(VARCHAR(10), dateadd(day,2,getdate()),101) THEN 1
ELSE 0
end without_cast,
case
when CAST('2017-01-08' AS DATE) > CONVERT(VARCHAR(10), dateadd(day,2,getdate()),101) THEN 1
ELSE 0
end with_cast

enter image description here

所以你需要的是:

  SELECT * 
FROM dbo.INVOICE i 
WHERE MVT_TYPE = '122' AND SALESREF IS NOT NULL AND CAST(POSTDATE AS DATE) > CONVERT(VARCHAR(10), dateadd(day,2,getdate()),101) 
AND NOT EXISTS (SELECT 1 
FROM dbo.INVOICE 
WHERE DEBIT = 'H' AND  MVT_TYPE = '000' AND SALESREF = i.SALESREF )

答案 2 :(得分:0)

您的问题是,您将notifyDataSetChanged存储为date

要正确比较2个日期,您应该比较他们的DATE rappresentation,而不是字符串。

所以我建议你把你的varchar转换成日期,即代替      varchar

您应该使用CAST(POSTDATE AS DATE) > CONVERT(VARCHAR(10), dateadd(day,2,getdate()),101)

DATEFROMPARTS函数从SQL Server 2012开始可用,如果您使用的是早期版本,请告诉我,我将重写我的代码