【问题标题】:Problem with Sql Server query using BETWEEN in where with DATETIME在 DATETIME 中使用 BETWEEN 的 Sql Server 查询出现问题
【发布时间】:2009-09-22 17:47:52
【问题描述】:

我有一个存储过程,它遍历财政年度中的几个月,并计算每个月的项目。我知道事实上有 176 个项目,但是当我运行它时,它返回的总计数为 182。我尝试从 @EndDate 中删除一秒,但我的总计数为 165。所以我要么计算项目两次,要么不算全部。谁能帮助我在这里做错了什么?下面是我正在做的精简版:

DECLARE @Date DATETIME
DECLARE @EndDate DATETIME

SELECT @Date = CAST((@Year - 1) as VARCHAR) + '-07-01'
SELECT @EndDate = DATEADD(Month, 1, @Date)


DECLARE @Count INT
SELECT @Count = 0
WHILE @Count < 12

BEGIN

    SELECT 
        COUNT(yai.ID)
    FROM
        table_1    yai 
        INNER JOIN table_2 yat ON yai.ID = yat.ID 
    WHERE
        (yat.Date_Received BETWEEN CONVERT(VARCHAR, @Date, 101) AND CONVERT(VARCHAR, @EndDate, 101))  AND 
        yai.Pro_Type = @Value AND yat.Type = 'PC'

    SELECT @Count = @Count + 1
    SELECT @Date = DATEADD(MONTH, 1, @Date)
    SELECT @EndDate = DATEADD(MONTH, 1, @EndDate)

END

【问题讨论】:

  • yat.date_received 的类型是什么?
  • 忽略类型为 101 的转换,这只是我在发布此代码之前尝试过的。它们是日期时间字段,我正在尝试与直接的日期时间值进行比较

标签: sql-server datetime stored-procedures between


【解决方案1】:

介于两者之间,因此您的 1 秒减法应该存在(甚至是一天)。我的猜测是有些 yais 没有对应的 yat。

编辑:您的代码是伪造的。除了等于 101 格式之外,您无法进行比较。

【讨论】:

  • +1 表示无法与格式 101 进行比较,除了相等性。
  • 对不起,我最初没有101转换,那只是我尝试过的。我一定是复制了那个代码而不是整个日期的实际代码
【解决方案2】:

从我的头顶。

SELECT DATEPART(month, yat.Date) as month, COUNT(yai.ID)
FROM table_1 yai 
INNER JOIN table_2 yat ON yai.ID = yat.ID 
WHERE
    yai.Pro_Type = @Value AND yat.Type = 'PC' 
    AND DATEPART(year, yat.Date)=@Year
GROUP BY DATEPART(month, yat.Date)
ORDER BY DATEPART(month, yat.Date)

【讨论】:

  • 这行得通,但我需要做一个从 7 月开始的财政年度。
  • 这已经足够接近我所需要的,我可以对其进行修改以使其工作。
【解决方案3】:

我曾经说过一些有趣的话,比如我知道有 50 个项目,而 sql 返回 60...

我发现我总是错的! :)

尝试从日期和时间字段中去除时间:

DATEADD(d, DATEDIFF(d, 0, GetDate()), 0)

【讨论】:

  • 我知道这个数字,因为我数过了。此外,我还有其他报告查询以其他方式将其分解。我的所有数字都匹配,除非我按月细分。
【解决方案4】:

你不能这样做吗?以下查询将为您提供按月分组的计数。如果将其放在视图中,则可以从视图中进行选择,并使用 where 子句按您感兴趣的年份和月份进行过滤。

select year(yat.Date_Received) as year, month(yat.Date_Received) as month, count(*) as count
    count(yai.ID)
from table_1 yai 
inner join table_2 yat on yai.ID = yat.ID 
where yai.Pro_Type = 'some_value' 
    and yat.Type = 'PC'
group by year(yat.Date_Received), month(yat.Date_Received)

【讨论】:

    【解决方案5】:

    这是 SQL 代码中不必要循环的典型案例,但如果您想通过循环解决此问题,请将您在循环中的选择更改为:

     SELECT 
            COUNT(yai.ID)
    

    到:

     SELECT 
         @Date,@EndDate,*
    

    然后查看输出并检查返回的行

    【讨论】:

      【解决方案6】:

      为什么不将日历月份转换为绝对整数引用,如下所示:

      DECLARE @BeginDate datetime = '7/1/2008'
      DECLARE @EndDate datetime = '6/30/2009'
      --
      -- Convert calendar months into an absoulte integer:
      --
      DECLARE @BeginMonth int = (DatePart(year, @BeginDate) * 12) + DatePart(month, @BeginDate)
      DECLARE @EndMonth int = (DatePart(year, @EndDate) * 12) + DatePart(month, @EndDate)
      
      SELECT COUNT(yai.ID)
      FROM table_1 yai
      INNER JOIN table_2 yat ON yai.ID = yat.ID
      WHERE (DatePart(year, yat.Date_Received) * 12) + DatePart(month, yat.Date_Received) 
          BETWEEN @BeginMonth AND @EndMonth)
      AND yai.Pro_Type = @Value
      AND yat.Type = 'PC'
      

      【讨论】:

        【解决方案7】:

        我发现这个问题是因为我在使用 Between 的查询中使用 string date 时遇到了麻烦,而我正在使用 metadata,我的同事帮助了我,所以我希望这个对你也有帮助:

        N'convert(date,[fld_myDate]) Between  convert(date,''01/01/2016'') AND convert(date,''08/26/2017'') '
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-03-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-10-07
          • 1970-01-01
          相关资源
          最近更新 更多