MS Chart控件 - 优化用于显示折线图类型的“零”Y值列的方法

时间:2010-06-17 16:54:13

标签: c# sql stored-procedures charts asp.net-charts

我正在使用VS 2010附带的Microsoft图表扩展。这很适合我的需求,但我遇到了烦恼,我正在寻找更优雅的解决方案。

绘制折线图时,要实现连续线,我需要所有X坐标的数据。我的数据集是按月按员工计算的销售数量,其中销售计数在Y上,而月份在X上。问题出现在没有为X值返回数据的情况下(即员工休假一个月)...所以这条线不连续。

我不确定图表控件中是否存在我忽略的设置,但我不太优雅的解决方案是在员工未发布销售的几个月内创建“假”零销售数据。

我在MS SQL中使用存储过程来创建我的数据集,其中每列是一个月,每行都是为员工。然后我在Chart控件中为每个员工创建一个新系列。

为了捕获我的零销售月份,我在SQL中创建了一个临时表。

CREATE TABLE @tblMonth (myMonth nvarchar(10), defaultCount int)
INSERT INTO @tblMonth VALUES (‘January’, 0)
…
INSERT INTO @tblMonth VALUES (‘December’, 0)

然后我在我的实际数据记录上执行临时表的连接并使用

ISNULL (realData.Count, tblMonth.defaultCount) 

获取我的'假'零销售数据。

这有效......但感觉对我来说真的很奇怪...我不禁觉得我忽略了一些更符合我目的的简单事物。再一次,我有这个工作......但总是寻找更好的做事方式和扩展我的知识基础...。如果有人有关于如何更好地完成上述工作的建议,我会喜欢一些建议或反馈。

1 个答案:

答案 0 :(得分:0)

如果tblMonth.DefaultCount始终为零,那么为什么不:

ISNULL (realData.Count, 0)

以下是我猜你的查询的样子:

SELECT
  sales_month = DATENAME ( month, s.sale_date )
  , sales_month_n = DATEPART( month, s.sale_date)
  , salesperson = e.employee_name
  , numb_of_sales = COUNT ( 1 )

FROM
 sales s
 JOIN employee e
   ON s.employee_id_salesperson = e.employee_id
WHERE s.sale_date >= '1/1/2010' and s.sale_date < '1/1/2011'
GROUP BY 
  DATENAME ( month, s.sale_date ), e.employee_name, DATEPART( month, s.sale_date)

- 工作正常,直到你有一名员工在六月,七月和八月起飞。您仍然希望它们显示在结果集中,但零销售

CREATE TABLE @tblMonth (myMonth nvarchar(10), n tinyint) 
    INSERT INTO @tblMonth VALUES ('January', 1) 
    ... 
    INSERT INTO @tblMonth VALUES ('December', 12)


SELECT
    all_possibles.sales_month
    , all_possibles.salesperson
    , ISNULL ( actual.numb_of_sales, 0 )
FROM 
    (
        SELECT
          sales_month = myMonth
          , sales_month_n = n
          , salesperson = e.employee_name
        FROM
            employee e
            ,@tblMonth M
    )all_possibles
    LEFT JOIN 
    (
        SELECT
          sales_month_n = DATEPART( month, s.sale_date)
          , salesperson = e.employee_name
          , numb_of_sales = COUNT ( 1 )
        FROM
         sales s
         JOIN employee e
           ON s.employee_id_salesperson = e.employee_id
        WHERE s.sale_date >= '1/1/2010' and s.sale_date < '1/1/2011'
        GROUP BY 
           e.employee_name, DATEPART( month, s.sale_date)
    )actuals
        ON 
        (
            all_possibles.salesperson = actuals.salesperson
            AND all_possibles.sales_month_n = actuals.sales_month_n
        )

很抱歉这个冗长的回答。希望你放心,你是在正确的轨道上。祝你好运!

至于kludgy - 而不是@tblMonth,我在实用程序/资源数据库中使用永久表。它已经填充了当天每分钟的记录,或者在这种情况下,记录了一年中每个月的记录。这些类型的表,忘记了它们的名称 - 也许是事实表的一种形式?在寻找或填补数据空白时非常有用。