3

我有一个销售表:

id_item, quantity, date_time

我需要的是总结一个月内售出的物品,然后将它们除以选定月份中的月份天数。

示例 - 用户选择 10 月 1 日至 12 月 31 日的日期。我需要显示 items_sold/days_of_month:

Month  Items sold  Days of month  Items/Day
Sep        25           30           0.83333
Oct        36           31           1.16
Dec        15           31           0.4838

我必须按种类指定。该种类是从另一个名为 Items 的表中获得的。我使用日期格式dd/mm/yy

select
   month(date_time),
   sum(quantity) / (select(datepart(dd,getdate())))
from
   sales v
   join items a on v.id_item=a.id_item
where
   a.kind='Kind of Item'
   and cast(Convert(varchar(10), date_time, 112) as datetime)
      between '01/10/2012' and '31/12/2012'
group by
   month(date_time)

我的问题是选择月份的天数,如何选择 x 个月数并将每个月的总和(数量)除以每个月的天数?

我知道这部分代码只选择当月的日期:

(select(datepart(dd,getdate())))
4

1 回答 1

4

试穿这个尺寸:

DECLARE
   @FromDate datetime,
   @ToDate date; -- inclusive

SET @FromDate = DateAdd(month, DateDiff(month, 0, '20121118'), 0);
SET @ToDate = DateAdd(month, DateDiff(month, 0, '20121220') + 1, 0);

SELECT
    Year = Year(S.date_time),
    Month = Month(S.date_time),
    QtyPerDay =
       Sum(s.quantity) * 1.0
       / DateDiff(day, M.MonthStart, DateAdd(month, 1, M.MonthStart))
FROM
    dbo.Sales S
    INNER JOIN dbo.Items I
       ON S.id_item = I.id_item
    CROSS APPLY (
       SELECT MonthStart = DateAdd(month, DateDiff(month, 0, S.date_time), 0)
    ) M
WHERE
    I.kind = 'Kind of Item'
    AND S.date_time >= @FromDate
    AND S.date_time < @ToDate
GROUP BY
    Year(S.date_time),
    Month(S.date_time),
    M.MonthStart

它将选择由FromDateand部分包围的任何完整月份ToDate。如果列是整数,则该* 1.0部分是必需的,否则您将得到整数结果而不是小数结果。quantity

一些风格注释:

  • 不要在列上使用字符串日期转换来确保您得到一整天。这将完全阻止使用任何索引,需要更多 CPU,而且还不清楚(样式 112 又做了什么!?!?)。要包含完整的日期期间,请使用我在查询中显示的内容DateCol >= StartDateDateCol < OneMoreThanEndDate。搜索“sargable”以了解这里的一个非常关键的概念。一个非常安全和有价值的一般规则是,如果可以重写条件来避免它,则永远不要将列放在表达式中

  • 为表设置别名很好,但是您应该在整个查询中为每一列使用这些别名,就像我在查询中所做的那样。我认识到别名 V 和 A 来自另一种语言,因此它们在那里是有意义的——通常尝试使用与表名匹配的别名。

  • 请在您的对象中包含架构名称。不这样做并不是一个巨大的禁忌,但有一定的好处,这是最佳实践。

  • 当您提出问题时,解释所有逻辑会很有帮助,这样人们就不必猜测或询问您——如果您知道(例如)用户可以输入月中日期但您需要整月,那么请指出在您的问题中并说明需要做什么。

  • 提供 SQL Server 的版本有助于我们将所需的语法归零,因为以前的版本表达力较差。通过告诉我们版本,我们可以为您提供最好的查询。

注意:将日期计算数学放在查询本身没有错(而不是使用 SET 来做)。但我想你会在存储过程中对此进行编码,如果是这样,使用 SET 就可以了。

于 2012-12-20T19:54:18.930 回答