平均值不计算零C#

时间:2014-08-05 07:11:26

标签: c# sql asp.net

请参阅此链接:Standard HTML table with total from SQL Server table

运行“平均”记录时,如何跳过零值? 例如:

ID     Number01     TheDate     Number02
----------------------------------------
1      10           01/06/2014  5
2      20           02/06/2014  0
3      30           03/06/2014  15
4      50           04/06/2014  60
5      0            05/06/2014  0
6      0            06/06/2014  0
7      0            07/06/2014  0
TOTAL  110          -           80
AVE    27.50        -           26.67

检查上表。
'Number01'字段,如果我运行所有记录的平均公式。平均值是15.71,但如果我跳过零值,平均值是27.50。也适用于'Number02'字段。

这是我的代码背后:

int totnum1 = 0;
decimal totnum2 = 0;
int numRow = 0;
decimal avg1 = 0;
decimal avg2 = 0;

totnum1 += reader.GetInt32(1);
totnum2 += reader.GetInt32(3);
numRow ++;

avg1 = totnum1 / numRow;
avg2 = totnum2 / numRow;

public string getWhileLoopData() {
    string htmlStr = "";
    SqlConnection thisConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString);
    SqlCommand thisCommand = thisConnection.CreateCommand();
    thisCommand.CommandText = "SELECT * FROM MyTable WHERE TheDate = @TheDate";
    thisCommand.Parameters.AddWithValue("@TheDate", txtDate.Text);

    int totnum1 = 0;
    decimal totnum2 = 0;
    int numRow = 0;
    decimal avg1 = 0;
    decimal avg2 = 0;

    thisConnection.Open();
    SqlDataReader reader = thisCommand.ExecuteReader();

    while (reader.Read()) {
        int id = reader.GetInt32(0);

        int Number01 = reader.GetInt32(1);
        DateTime TheDate = reader.GetDateTime(2);
        Decimal Number02 = reader.GetDecimal(3);

        totnum1 += reader.GetInt32(1);
        totnum2 += reader.GetInt32(3);
        numRow ++;

        //string Pass = reader.GetString(2);
        htmlStr += "<tr><td>" + id + "</td><td>" + Number01 + "</td><td>" + TheDate + "</td><td>" + Number02 + "</td></tr>";
    }

    thisConnection.Close();

    avg1 = totnum1 / numRow;
    avg2 = totnum2 / numRow;

    htmlStr += string.Format("<tfoot><tr><td>Tot</td><td>{0}</td><td></td><td>{1}</td></tr>", totnum1 , totnum2 );
    htmlStr += string.Format("<tfoot><tr><td>Avg</td><td>{0}</td><td></td><td>{1}</td></tr></tfoot>", avg1 , avg2 );
    return htmlStr;
}

3 个答案:

答案 0 :(得分:1)

在不知道您的数据结构的情况下很难给出确切的代码,但假设您正在寻找C#代码,LINQ将很好地完成这项工作。否则,SQL中的WHERE会。我会根据一些事情在它们之间进行选择,但主要是你是否需要将数据拉下来。因此,例如,如果您打印出一个包含总计行的表,我将使用LINQ解决方案。但是,如果您只想查看要显示的平均值,请使用WHERE

int[] args = new int[] { 0, 10, 25, 0, 70 };

return args.Where(c => c != 0).Average();

修改

按照您的要求查看链接,我只需添加List<int>来存储所有值,然后对此运行此查询。这不是最有效的解决方案,但我不会觉得效率在这里比可读性更重要,如果您的记录很少,差异就不会明显。

答案 1 :(得分:0)

如果你想在建立平均值之前过滤掉零...那么你必须在建立平均值之前过滤掉零:

SELECT AVG(Value)
FROM   YourTable
WHERE  Value <> 0

答案 2 :(得分:-1)

通过您已关联的帖子。您需要做的是更改以下行:

totnum1 += reader.GetInt32(1);
totnum2 += reader.GetInt32(3);
numRow ++;

到此:

totnum1 += Number01;
totnum2 += Number02;
if(Number01 != 0 || Number02 != 0) numRow ++;
只有当前行中的相应列不为零时,

numRow才会递增,因此Avg表达式的denom将只计算非零行。