SQL - Mathematical (Min - Max Normalisation)

时间:2019-02-18 00:21:10

标签: c# sql sql-server math sqlcommand

I want to normalization operation in my code. I have a SQL - Server table, it has 3 columns; first column has single words, second column has single words, third column has integer values. I researched it and I thought I should do a sql query rather than writing a complex C# code. I have a DataGridView and it look like that (Example 1);

           Column 1          Column 2
         ------------------------------
          hello my             4500
          crazy day            3200
          such a               2885
          new coder            1010

Normalization formula : ((Value / Max Value) * 100)

Problem : It works good in first step, after normalization operation my DataGridView looks like that;

           Column 1          Column 2
         ------------------------------
          hello my             %100
          crazy day            %71.11
          such a               %64.11
          new coder            %22.44

But when I upload other links to the system like that (Example 2);

           Column 1          Column 2
         ------------------------------
          maybe today          2560
          it mine              1405
          the world            800
          welcome there        400

It returns my normalized values like that, because it takes maximum value 4500 everytime;

           Column 1          Column 2
         ------------------------------
          maybe today          %56.88
          it mine              %31.22
          the world            %17.77
          welcome there        %8.88

But, I want it to be considered in itself. When I upload new link, it should find the maximum value in links and return normalization values according to that. So, my DataGridView should look like that;

           Column 1          Column 2
         ------------------------------
          maybe today          2560
          it mine              1405
          the world            800
          welcome there        400




           Column 1          Column 2
         ------------------------------
          maybe today          %100
          it mine              %54.88
          the world            %31.25
          welcome there        %15.62

It's my code;

   string myCommand = "SELECT c1, c2, ((CONVERT(DECIMAL(18,2), c3) / (SELECT MAX(c3) FROM myTableName)) * 100) AS normalizedc3 FROM myTableName WHERE c1='" + sr[mssi1] + "' AND c2='" + sr[mssi2] + "' OR c2='" + sr[mssi1] + "' AND c1='" + sr[msii2] + "'";

It's my second code for it;

    string myCommand = "select c1, c2, c3 / m.max_c3 * 100 normalizedvalue from myTableName inner join (select convert(float, max(c3)) max_c3 from myTableName) m on 1 = 1 WHERE c1='" + sr[mssi1] + "' AND c2='" + sr[mssi2] + "' OR c2='" + sr[mssi1] + "' AND c1='" + sr[mssi2] + "'";

It's my full code;

            for (int mssi1 = 0; mssi1 < sr.Length; mssi1++)
            {
                for (int mssi2 = mssi1 + 1; mssi 2< sr.Length; mssi2++)
                {
                    string myCommand = "SELECT c1, c2, ((CONVERT(DECIMAL(18,2), c3) / (SELECT MAX(c3) FROM myTableName)) * 100) AS normalizedc3 FROM myTableName WHERE c1='" + sr[mssi1] + "' AND c2='" + sr[mssi2] + "' OR c2='" + sr[mssi1] + "' AND c1='" + sr[mssi2] + "'";
                    SqlDataAdapter sadapter = new SqlDataAdapter(mc, conection);
                    DataTable dt = new DataTable();
                    sadapter.Fill(dt);
                    foreach (DataRow row in dt.Rows)
                    {
                        bool removeMyDup = dgv2.Rows.Cast<DataGridViewRow>().AsEnumerable().Any(x =>
                            Convert.ToString(x.Cells["Column1"].Value).Split(' ')[0] == row["c1"].ToString() &&
                            Convert.ToString(x.Cells["Column1"].Value).Split(' ')[1] == row["c2"].ToString() &&
                            Convert.ToInt32(x.Cells["Column2"].Value) == Convert.ToInt32(row["c3"])
                        );
                        if (!removeMyDup)
                            dgv2.Rows.Add(row["c1"].ToString() + " " + row["c2"].ToString(), row["c3"]);
                    }
                 }
            }

Note 1 : 4500 is not my maximum value, it's only an example. My maximum value is 1400000 and my minimum value is 10. But everytime I upload different links the system. Maximum and minimum number always change...

Note 2 : If you want I can share all of my code, please leave a comment for it.

How should I fix it in a sql command or c# code, I'm waiting for your helps. Thank you.

2 个答案:

答案 0 :(得分:0)

You could do something like add a BATCH_ID column to your table, and each set of data that you add gets a unique BATCH_ID. Then your query can become something like:

string myCommand = 
"SELECT c1, c2, 
((CONVERT(DECIMAL(18,2), c3) / (SELECT MAX(c3) FROM myTableName b where b.BATCH_ID = A.BATCH_ID)) * 100) AS normalizedc3 
FROM myTableName a 
WHERE c1='" + mfa[msi] + "' AND c2='" + msa[mssi] + "' OR c1='" + msa[mssi] + "' AND c2='" + mfa[msi] + "'";

If you mean just the max of the resultset then you can use Gordon's answer:

string myCommand = 
"SELECT c1, c2, 
c3 * 100.0 / max(c3) over () as normalizedc3
FROM myTableName a 
WHERE c1='" + mfa[msi] + "' AND c2='" + msa[mssi] + "' OR c1='" + msa[mssi] + "' AND c2='" + mfa[msi] + "'";

答案 1 :(得分:0)

如果您有SQL查询,则可以按以下方式获取所需的值:

select t.*,
       column2 * 100.0 / max(column2) over () as normalized_value
from t;

如果添加一个where子句,则用于规范化的最大值是所选数据的最大值。

Here是db <>小提琴。