首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在数据库中存储每周目标

在数据库中存储每周目标
EN

Stack Overflow用户
提问于 2010-12-10 12:55:27
回答 3查看 2.7K关注 0票数 1

我有以下要求

代码语言:javascript
运行
复制
Sales Officer: Bob

             Week1 Week2  Week3 ................. Week52
    Prod1     10    15    12    .................    14
    Prod2     20    14    10    .................    17
    .                                                 .   
    .                                                 .
    .                                                 .

销售主管每周为每位销售人员设定目标。销售员可以根据设定的目标,通过类似的网格,每天输入每种产品的实际销售。

编辑

在上述情况下,主管已经为第一周设定了10个单元的目标,现在销售官将以1,2,0,1,3,2=9(第一周实际销售)的方式进入销售,因此,在第一周他已经卖出了9个单元。

我已经创建了“员工”和“产品”表。关于如何在存储目标的数据库中存储、days、weeks、和实际销售的最佳实践,可以提供任何一个指南吗?

我正在考虑在下表中存储数据

代码语言:javascript
运行
复制
EmpSales (EmployeeID,ProductID,SaleTarget,Actual Sale,Date,WeekNo,Month)

提前感谢

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-12-10 13:03:11

就我个人而言,我会选择一个更通用的“期间”表。

期间(periodId,startDate,endDate,weekNo,月份,年份)

然后添加

empSales(EmployeeId,ProductId,SaleTarget,ActualSale,periodId)。

这有点灵活(您可以很容易地引入不同的时间跨度,或者使相对周字段为空,或者定义一些规则来映射“标准”周上的周期),这样就减少了冗余(注意月份和周是如何从empSales表中移开的),它允许您进行报告和计算(顺便说一下,您没有包含一个年份字段,有原因吗?)

总结内容应该更容易,因为假设您有按日排序的销售额,除非您想在DB中复制"week“字段,否则在间隔之间对这些内容进行汇总比较容易。

还请注意,您可以很容易地在不同的重叠期上设置目标。

例如,您可以为11月22日至28日的周设定一个每周的目标(我正在使用欧洲大会的一周从星期一开始),并在黑色星期五设定一个特殊的一天周期。

所以:

代码语言:javascript
运行
复制
Period:  

 periodId|startDate  |endDate    |weekNo|Month    |  Year|
  0030020|22-NOV-2010|28-NOV-2010|  43  |November | 2010 |
  0030026|26-NOV-2010|26-NOV-2010| null |November | 2010 |

empSales:

 EmployeeId|ProductId|SaleTarget|ActualSale|periodId|
     567689|   788585|      58  |       42 | 0030020|
     567689|   788585|      28  |       32 | 0030026|

请注意,567689员工是如何错过了每周的目标,但却成功地超过了他的黑色星期五目标。

顺便说一下,在处理这个示例时,我认为最好删除"empSales“表,将其重命名为"empTargets":

empTargets(EmployeeId,ProductId,SaleTarget,periodId)。

因为实际的销售额很容易通过UDF或者放在视图中实时计算--毕竟,它只是一个

代码语言:javascript
运行
复制
select sum(items_sold) 
from sales 
where sales.employeeId = empTargets.employeeId and 
      sales.ProductId= empTargets.ProductId and 
      sales.saleDate between empTargets.startDate and 
                             empTargets.endDate)

因此,不需要直接将其存储在表中(事实上,在返回项目或其他今后更正的情况下,它可能成为负担)。

票数 1
EN

Stack Overflow用户

发布于 2010-12-13 08:55:59

在纯关系建模术语中,这是非常容易的。我不认为有必要进行任何形式的“去分化”。

如果您不熟悉关系数据库建模标准,可能会有所帮助。

纯5NF;完全声明引用完整性;没有full,没有更新异常;没有GROUP BYs;纯日期算法。

  • SaleTargetSaleActual通过投影进行比较,并且可能在相同的结果集中。如果您有月度和年度销售会计,所需的扩展是一个具有一些控制或结构的通用日历表;例如。类似于Week,包括每个月和一年的行。让我知道,我会更新模型,

  • ,我说5NF,因为这是我为了消除更新异常而提供的最小值,而且大多数建模师都很熟悉它。但是,如果它不能吓跑您,那么这两个销售表实际上是第六标准的,它允许在没有临时表或复杂SQL的情况下进行完整的旋转(周或数月之间;产品或员工向下;反之亦然;任何组合)。(只要问一问)

我认为这甚至可能是不言自明的,但我将提供动词短语,其中详细说明了业务规则,这只是因为有三个家长参与其中:

  • 每名员工被排定为产品周SaleTarget
  • 每个产品被员工排定为SaleTarget周
  • 每个员工在第一天完成了产品的SaleActual
  • 每个产品都是由员工在日期

F 229完成的

比较

我应该提到的

  1. 。注意,没有垂直(行)或水平(列)重复。当列被复制(例如,StartDate EndDate )时,您已经破坏了3NF (引入了函数依赖项),并引入了一个更新异常。任何行中的EndDate,都是下一行中的StartDate (减1秒算作欺骗,是一个设计);在更新时,现在必须更改两行而不是一行。更重要的是,这种结构是如此简单(它不是时间序列或“时间”需求),也不需要EndDate

对评论的答复

  1. 数据模型已经更新,以包含MonthYear需求。现在需要对SaleTarget设置一个检查约束,以确保DateType是一周内的W。加载日期表很简单,您不需要发布在SQLTeam上的无意义代码(手动重复剪切粘贴);它们以愚蠢而闻名,SQLTeam SaleActual表现在包含了每日、每周、每月和年度值。当然,您可以在每周、每个月、每一天的第一天进行编程总结。首先,将新行添加到Date.
  2. 5NF非常重要,这是目前标准遵从性所需的最低要求,因此您需要适应它。基本上,在3NF和5NF之间,学者们(再加上维基百科( Wikipedia )发布了完全不正确的条目)之间有很多争论。5NF的简短而甜蜜的定义是,它是3NF的原意,没有数据重复,没有更新异常(目前还没有重复的列要更新约6NF )。任何表在6NF,在5NF (和4NF和BCNF和3NF)。只需把这两个销售表当作5NF。当你必须写一份有中心的报告时,比如说一年后,你就会意识到这种结构的价值。
票数 3
EN

Stack Overflow用户

发布于 2010-12-10 14:10:12

我个人会将目标和实际值分别存储在不同的行中,并且很可能存储在单独的表中:

目标: EmployeeId,PeriodId,ProductId,TargetValue

销售: EmployeeId,PeriodId,ProductId,SalesValue

事实上,在集成系统中,第二个表通常是不必要的(假设您有一个完整的销售记录系统,这应该是对实际记录的销售的预测/视图-根据该子系统的模型适当分配员工、期间和产品)。

为了满足您的日历要求,我几乎肯定会有一个日期表,该表将允许您确保所有用于定义周和月的业务规则,而不需要复杂的日期逻辑。然后,通过与日历表的联接,可以方便地确定周期和聚合。

因此,ActualSales看起来应该是这样的(只有一个泛型句点表,它本身可能是一个句号和日期表):

代码语言:javascript
运行
复制
SELECT sp.EmployeeId
       , p.ProductId
       , pd.PeriodType
       , pd.PeriodId
       , SUM(id.Quantity * id.UnitProce) AS TotalSales
FROM Invoice AS i
INNER JOIN InvoiceDetail AS id
    ON id.InvoiceId = i.InvoiceId
INNER JOIN Employee AS sp
    ON sp.EmployeeId = i.SalesPersonId
INNER JOIN Product AS p
    ON id.ProductId = p.ProductId
INNER JOIN Period AS pd
    ON pd.StartDate <= i.InvoiceDate
    AND pd.EndDate > i.InvoiceDate
GROUP BY sp.EmployeeId, p.ProductId, pd.PeriodType, pd.PeriodId

在这种情况下,如果您有重叠的周期(比如日、周、月),数据就会被复制,所以您只需要聚合一种类型的周期--这就是为什么我在这个示例视图中专门包含了它,尽管它在这里是多余的。

我预计通用期间表将类似于:

代码语言:javascript
运行
复制
PeriodId
PeriodType
StartDate
EndDate

这将预先填充要报告的各个时间段:

代码语言:javascript
运行
复制
'Q', 1/1/2010, 4/1/2010
'M', 1/1/2010, 2/1/2010
'M', 2/1/2010, 3/1/2010
'M', 3/1/2010, 4/1/2010
'W', 1/3/2010, 1/10/2010
'W', 1/10/2010, 1/17/2010
etc.
'D', 1/1/2010, 1/2/2010
'D', 1/2/2010, 1/3/2010
etc.

担心假期是没有什么意义的,只是如果他们不工作,你可能不会分配一个目标,这主要是关于管理任务,这样他们大概是现实的。您可以有一个有各种标志的日历表。

代码语言:javascript
运行
复制
Calendar
DateId
Date
IsHoliday

然后,当你加入计算一个时期的假期/周末的次数时,你可以把它包括在内。

这通常是会计/业务方面的事情,但您可能需要研究如何标准化您的日历。例如,在媒体购买电视广告时,它们使每个“季度”相等,并使每个“月”标准化--4周、4周、5周。显然,他们对假日和特殊电视事件有例外,但这有助于理顺会计和比较类似时期更容易。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4409003

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档