我想在我的代码中进行规范化操作。我有一个SQL-Server表,它有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] + "'";
这是我的完整代码;
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#代码中修复它,我正在等待你的帮助。谢谢。
您可以执行诸如向表中添加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] + "'";
如果你只是结果集的最大值,那么你可以使用Gordon的答案:
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] + "'";
如果您有SQL查询,那么您可以获得所需的值:
select t.*,
column2 * 100.0 / max(column2) over () as normalized_value
from t;
如果添加where
子句,则用于规范化的最大值是所选数据的最大值。
Here是一个db <>小提琴。