在.net core中运行多个sql查询以获取矩阵结果

wmtdaxz3  于 2021-08-09  发布在  Java
关注(0)|答案(2)|浏览(284)

我试图从数据库中获取结果,以生成某种矩阵结果,并将其发送回前端。关键是我有x轴和y轴的百分位值,我把它们分成10部分,得到10x10的表格。为了得到每个值,我计算不同的用户ID,所以它像1-1,1-2。。。10-10.
这是我目前的代码(虽然还没有完成,只是我到目前为止的想法),我想改进,因为一个接一个地运行100个查询似乎不是一个好的解决方案。但是,我有点纠结于如何提高性能,以及是否应该返回lenght=100的dictionary或多维矩阵数组中的结果,以使其成为一个好的实践代码。提前谢谢大家的提示,我的代码如下:

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

所以会有100行这样的线。 ProbabilityAlive 以及 SpendAverage 如果是来自前端的列标题,则可能有任何其他列标题。对于这两列,我计算百分位值,然后我把它分成十部分,一部分是x轴,另一部分是y轴。然后我使用上面的sql查询来获取每个矩阵值的值,因为矩阵是10x10,所以这个值变成100个查询。
因此,我想得到100个整数值,但我仍在努力弄清楚是否最好将数据放入字典中,然后将范围为x-y和value的key作为select结果(例如。 "0-1", 5472" ),或是将其放入多维数组或其他什么。我有 xDict 包含范围作为键,例如“0-1”,然后sql语句probabilityalive>0和probabilityalive<1,然后为y轴从 yDict . 我有两张单子 x 以及 y 包含10个用于这些范围的双精度值

7d7tgy0s

7d7tgy0s1#

看起来您想计算特定范围的用户计数 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

可以为特定数量的箱子动态创建边界,例如使用数字表。你必须提供更多关于你真正想要什么的信息

wi3ka0sx

wi3ka0sx2#

只要有两个维度,最容易做和维护的就是生成一个tsql存储过程,输出所需的元组(默认输出)。把从前端得到的输入作为参数传入。
如果您有一个返回json(或xml)的web服务httpget的功能呢?用tsql来模拟它。
因为您可以直接访问sql server,所以可以调用类型为“get”的存储过程来传递参数,并得到一个元组结果。易于独立于.net核心应用程序编写和测试。也会很快。
键入“get”=只是一个只读sp,我将我的usp\u get\u method\u name命名。我还使用sps保存sql端验证,所以我称它们为usp\u put\u method\u name。
干杯

相关问题