c# - 在 .NET Core 中运行多个 sql 查询以获取矩阵结果
问题描述
我正在尝试从数据库中获取结果以生成某种矩阵结果以发送回前端。关键是我有 X 轴和 Y 轴的百分位值,我将其分成 10 个部分以获得 10x10 表。为了得到每个值,我计算不同的用户 ID,所以它就像 1-1、1-2 ... 10-10。
这是我当前的代码(虽然尚未完成,只是我目前的想法),我想改进它,因为一个接一个地运行 100 个查询似乎不是一个好的解决方案。但是,我有点卡住了如何使性能更好,以及我是否应该在长度为 100 的字典中返回结果,或者返回多维矩阵数组以使其成为一个很好的实践代码。提前感谢任何人的提示,我的代码如下:
public async Task GenerateMatrix(List<double> x, string xAxis, List<double> y, string yAxis, Parameters parameters)
{
IDictionary<string, string> xDict = GenerateRanges(x, parameters.XAxis);
IDictionary<string, string> yDict = GenerateRanges(y, parameters.YAxis);
var innerJoin = GenerateInnerJoin(parameters);
var whereClauses = GenerateWhereClause(parameters);
var sql = $@"SELECT COUNT(DISTINCT [dbo].[{nameof(Table)}].[{nameof(Table.UserId)}]) FROM [dbo].[{nameof(Table)}] {innerJoin} ";
if (whereClauses.Any())
{
sql += " WHERE " + string.Join(" AND ", whereClauses);
}
for (int i = 0; i < x.Count; i++)
{
var queryToExecute = "";
for (int j = 0; j < y.Count; j++)
{
queryToExecute = sql + " AND " + xDict.Values.ElementAt(i) + " AND " + yDict.Values.ElementAt(j);
var userCount = await Store().QueryScalar<int>(queryToExecute);
}
}
return null;
}
private IDictionary<string, string> GenerateRanges(List<double> axis, string columnTitle)
{
IDictionary<string, string> d = new Dictionary<string, string>();
for (int i = 0; i < axis.Count; i++)
{
var rangeSql = $@" [dbo].[{nameof(Table)}].[{columnTitle}]";
if (i == 0)
{
d.Add(axis[i].ToString(), rangeSql + " < " + axis[i]);
}
else if (i == axis.Count - 1)
{
d.Add(axis[i] + "+", rangeSql + " > " + axis[i]);
}
else
{
d.Add(axis[i-1] + "-" + axis[i], rangeSql + " > " + axis[i-1] + " AND " + rangeSql + " < " + axis[i]);
}
}
return d;
}
sql看起来像这样:
SELECT
COUNT(DISTINCT [dbo].[Table].[UserId])
FROM [Table]
WHERE Table.[ClientId] = '2'
AND [dbo].[Table].[ProbabilityAlive] < 0.1
AND [dbo].[Table].[SpendAverage] < 24.86
所以会有10000条这样的行。
ProbabilityAlive
并且SpendAverage
是来自前端的列标题,可能还有任何其他列标题。对于这两列,我计算百分位值,然后我将其分成十部分,一个是 X 轴,另一个是 Y 轴。然后我使用上面的 sql 查询来获取每个矩阵值的值,因为矩阵是 10x10,所以它变成了 100 个查询。
结果,我想获得 100 个整数值,我仍在试图弄清楚是否最好将数据放入字典中,然后将具有范围 xy 和值的键作为选择结果(例如 "0-1", 5472"
),或者是否将其放入多维数组或别的东西。我有xDict
包含范围作为键,例如“0-1”,然后是 sql 语句 ProbabilityAlive > 0 AND ProbabilityALive <1,然后为 Y 轴从yDict
. 然后我有两个列表x
,y
其中包含 10 个用于这些范围的双精度值
解决方案
看起来您想要计算 和 的特定范围的用户ProbabilityAlive
数SpendAverage
。
首先,您需要生成范围组合。在 SQL 中生成组合的简单方法是连接两个表或一组值。
如果您有两个表的范围值如下:
create table ProbabilityRanges
(
LowBound decimal(3,2), UpperBound(3,2)
)
create table SpendRanges
(
LowBound decimal(3,2), UpperBound(3,2)
)
您可以使用交叉连接来生成所有组合:
SELECT
SpendRanges.LowBound as SLow,
SpendRanges.UpperBound as SUpper,
ProbabilityRangers.LowBound as PLow,
ProbabilityRanges.UpperBound as PUpper
FROM ProbabilityRanges CROSS JOIN SpeedRanges
您可以使用这些组合来过滤和计算另一个表中在这些范围内的行:
SELECT
SpendRanges.LowBound as SpendValue,
SpendRanges.LowBound as ProbabilityValue,
Count(DISTINCT UserID) as Count
FROM SomeTable CROSS JOIN ProbabilityRanges CROSS JOIN SpeedRanges
Where
SomeTable.ClientID=2
AND SomeTable.SpendAverage >=SpeedRanges.LowBound
AND SpendAverage < SpeedRanges.UpperBound
AND SomeTable.ProbabilityAlive >= ProbabilityRangers.LowBound
AND SomeTable.ProbabilityAlive < ProbabilityRanges.UpperBound
GROUP BY SpendRanges.LowBound,SpendRanges.LowBound
可以为特定数量的 bin 动态创建边界,例如使用 Numbers 表。你必须提供更多关于你真正想要的信息
推荐阅读
- angular - Angular:多个下拉列表
- php - 哪种方法在服务器上保存拖放列表更有效;一个不断的ajax更新与手动保存按钮?
- excel - 用于存储和计算唯一 ID 出现次数的多维数组
- arrays - 在 MongoDB 中对对象数组中的项目使用 $rename
- asp.net-core - SignalR Core JS 客户端未在“升级”请求中传递授权标头
- javascript - 来自 lambda 函数的 API 网关的 502 内部服务器错误响应
- c# - 如何使用单输入文本框使用winform和socket编程c#将多个输入写入硬件?
- html - 让单选按钮标签在我检查后保持相同的颜色
- python - 在 python 中,有没有比 for 循环更快的方法来标记矩阵(3D 数组)?
- c# - 如何在这段代码中用 do-while 替换 while?