SQL - математический (мин - макс нормализация) - PullRequest
0 голосов
/ 18 февраля 2019

Я хочу нормализовать работу в моем коде.У меня есть таблица SQL-сервера, она имеет 3 столбца;первый столбец содержит отдельные слова, второй столбец содержит отдельные слова, третий столбец имеет целочисленные значения.Я исследовал это и подумал, что мне следует выполнить SQL-запрос, а не писать сложный код на C #.У меня есть DataGridView, и это выглядит так (Пример 1);

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

Формула нормализации: ((Значение / Макс. Значение) * 100)

Проблема: на первом этапе работает хорошо, после операции нормализации мой DataGridView выглядит так:

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

Но когда я загружаю другие ссылки в систему, как это (Пример 2);

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

Он возвращает мои нормализованные значения какэто потому, что оно принимает максимальное значение 4500 каждый раз;

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

Но я хочу, чтобы оно рассматривалось само по себе.Когда я загружаю новую ссылку, она должна найти максимальное значение в ссылках и вернуть значения нормализации в соответствии с этим.Итак, мой DataGridView должен выглядеть так:

           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

Это мой код;

   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] + "'";

Это мой второй код для него;

    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] + "'";

Это мой полный код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"]);
                    }
                 }
            }

Примечание 1: 4500 - это не мое максимальное значение, это только пример.Мое максимальное значение - 1400000, а минимальное - 10. Но каждый раз я загружаю разные ссылки в систему.Максимальное и минимальное число всегда меняются ...

Примечание 2: Если вы хотите, чтобы я мог поделиться всем своим кодом, оставьте комментарий к нему.

Как мне исправить это в sqlкод команды или c #, я жду ваших подсказок.Спасибо.

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

Если у вас есть SQL-запрос, вы можете получить следующие значения:

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

Если вы добавите предложение where, максимальное значение, используемое для нормализации, - это максимум данныхвыбранный.

Здесь - это дБ <> скрипка.

0 голосов
/ 18 февраля 2019

Вы можете сделать что-то вроде добавления столбца BATCH_ID в свою таблицу, и каждый набор данных, который вы добавляете, получает уникальный BATCH_ID.Тогда ваш запрос может выглядеть примерно так:

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] + "'";

Если вы имеете в виду только максимальный набор результатов, вы можете использовать ответ Гордона:

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] + "'";
...