所以,我想在mssql中的两个日期之间检索数据。我有一张桌子,名字是FILES。我有2列,名称是NAME,RECORDDATE(nvarchar)。当我保存我的数据时,我从raddatetimepicker.text获取所以我的值是" 2015年12月22日星期二"。
我的查询是
select * from FILES where RECORDDATE>= '11 January 2015 Saturday' and RECORDDATE<= '24 October 2015 Monday'
这个查询有效,但是当我在2015年1月11日星期六更改&#39;到2015年1月28日周二&#39;它不起作用。它是如此有趣,因为我在1月21日的查询也工作但是当我写1月28日我得到0行。
我真的卡住了,不知道问题。
你的答案是真实的,但其他答案也是如此,所以我不知道如何将所有答案标记为答案:)谢谢你。这是我在一个月的自我训练后的第一个项目,所以不要太惊讶:D
答案 0 :(得分:1)
以下情况属实,条件是您的DATETIME
实际上是数据库中的DATETIME
字段。您目前将NVARCHAR
作为DateTimePicker
存储。 现在停止执行此操作并使用正确的类型!
任何DateTime
都应该有一个返回DateTime recordDate = dtpDate.Value;
using (SqlCommand cmd = new SqlCommand("insert into FILES (NAME, RECORDDATE) VALUES (@name, @recorddate)", conn))
{
cmd.Parameters.Add("@name", SqlDbType.NVarChar).Value = someName;
cmd.Parameters.ADd("@recorddate", SqlDbType.DateTime).Value = recordDate;
cmd.ExecuteNonQuery();
}
的属性。如果没有:转储并使用正确的。也就是说,您可以使用参数化查询来存储和查找您的记录。
插入将如下所示:
DateTime start = dtpStart.Value;
DateTime end = dtpEnd.Value;
using (SqlCommand cmd = new SqlCommand("select * from FILES where RECORDDATE BETWEEN @start and @end", conn))
{
cmd.Parameters.Add("@start", SqlDbType.DateTime).Value = start;
cmd.Parameters.Add("@end", SqlDbType.DateTime).Value = end;
using (SqlDataReader reader = cmd.ExecuteReader())
...
}
然后查询查询归结为:
String.Format
这样做可以解决以下问题:
答案 1 :(得分:0)
实际上你得到字符串比较,而不是日期比较,因为RECORDDATE是NVARCHAR(unicode字符串)。
第一个字符串以&#39; 28开始。&#39;所以它比以&#39; 24&#39;开头的字符串更大,所以你总是假的,因此是0行。
答案 2 :(得分:0)
由于将日期存储为字符串,您正在执行字符串比较,而不是日期比较。当您更新了值后,您正在检查28 January 2015 Tuesday
和24 October 2015 Monday
之间的字符串。鉴于较低的值更大,您将永远不会返回任何行。
如果要查找两个日期之间的值,最好将数据类型更改为DateTime
。
如果无法做到这一点,那么您可以将列转换为DateTime
,例如
SELECT * FROM FILES
WHERE RECORDDATE >= CAST('11 January 2015 Saturday' AS DATETIME)
AND RECORDDATE <= CAST('24 October 2015 Monday' AS DATETIME)
作为旁注,2015年1月28日是星期三,而不是星期二
此方法的一个缺点是您将无法在RECORDDATE
列上使用索引,因为查询将是非SARGable
答案 3 :(得分:0)
在您的比较中,您正在比较字符串,而不是日期。在SQL string comparison is done based on alphabetical order。在您的示例中,这意味着'28...' > '24...'
。
你应该
DATETIME
值或nvarchar
to DATETIME
作为旁注,包括工作日在内,没有必要检查日期范围,所以我建议删除它以避免错误。事实上,你的例子中似乎有一个错误:星期二应该是你问题的星期三。
答案 4 :(得分:0)
希望您可以修复您的数据......但根据您的示例日期,这里是一个CTE,它将修复您的日期并格式化您的数据,以便进行过滤。
WITH [SubDates] AS (
SELECT
[FILES].*
,SUBSTRING([FILES].[RECORDDATE], 0, PATINDEX('%20[0-9][0-9] %', [FILES].[RECORDDATE]) + 4) AS [RECORDDATE_Sub]
FROM [FILES]
), [AsDates] AS (
SELECT
[SubDates].*
,CASE ISDATE([SubDates].[RECORDDATE_Sub])
WHEN 1 THEN CONVERT(DATE, [SubDates].[RECORDDATE_Sub])
END AS [RECORDDATE_Fixed]
FROM [SubDates]
)
SELECT *
FROM [AsDates]
WHERE
[AsDates].[RECORDDATE_Fixed] BETWEEN '11 January 2015' AND '24 October 2015'
答案 5 :(得分:-1)
试试这个
select * from FILES where RECORDDATE between STR_TO_DATE('11 January 2015 Saturday',"%d %M %Y %W") and STR_TO_DATE('24 October 2015 Monday',"%d %M %Y %W")