我有一张桌子,这是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 |
答案 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
所以你需要的是:
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开始可用,如果您使用的是早期版本,请告诉我,我将重写我的代码