0

我正在解决这个问题:根据 table1 结果的条件,从连接 2 个或 3 个表的单行创建多个结果?虽然我希望我能接受Strawberry's建议,但我不能,所以我现在尝试在 C# 中而不是通过 DB 做更多事情,但也试图聪明地了解我使用了多少 CPU。

对于规模,table1 可能有 50,000 条记录,codetype其中包含必须评估的 20 个字段,然后才能匹配到 table2,它有大约 2,000 行,或者 table3,它可能有 200,000 行。为了避免敲击数据库,我将在内存中存储可能的内容,尽可能按日期限制结果,但我想避免每 20 个代码类型匹配有 2,000 个 foreach 循环。

首先,我从 table2 获得所需的结果,并将它们加载到 C# DataTable 中,存储为名为的变量descriptionLookup

id,    description
13    Item 13 Description
15    Item 15 Description
17    Item 17 Description
18    Item 18 Description
21    Item 21 Description
28    Item 28 Description
45    Item 45 Description

表 3 为lookupTable

id,  table2id
1    15
33   17
21   28

做一个简单的(不显示所有周围的代码,只是相关的):

var rawData = new DataTable();
using (OdbcCommand com = new OdbcCommand("SELECT id, description from table2", conn))
{
    using (OdbcDataReader reader = com.ExecuteReader())
    {
        rawData.Load(reader);
        conn.Close();
        return rawData;
    }

}

然后我将其分配给调用该函数的变量。现在我必须处理table1:

codeid1,codeid2,codeid3,...codeid20 ... codetype1,codetype2,codetype3,.....codetype20
18      13      1          33           0         0         1              1
13      21      45         0            0         1         0              0

使用 foreach 行,我需要评估每个 codetype 列是否为 1 或 0。当 codetype=1 时,我需要获取关联的 codeid,然后从我保存在内存中的数据中查找descriptionLookuptable2id是匹配idinlookuptable然后使用它来查找 table2 中关联字段的描述。

如果 codetype 为 0,我只需要匹配codeidtable2 中的相关描述字段。

我正在研究如何布局,我能想到的只有:

DataTable descriptionLookup= DB.ExecuteQuery("SELECT id, description from table2");
DataTable lookupTable= DB.ExecuteQuery("SELECT id, table2id from table3");
DataTable mainData= DB.ExecuteQuery("SELECT * from from table1");

foreach (var row in mainData)
{
    var manDataId = row.GetColumn("id");
    var subroutine = new Dictionary<string, string>();
    for (var index = 1; index < 20; index++)
    {
        string description;
        if (row.GetColumn("codetype" + index) == "1")
        {
            int idLookup = row.GetColumn(["codeid" +index]);
            foreach (var row2 in lookupTable)
            {
                if (row3.GetColumn("id") == idLookup)
                {
                    descriptionId = row3.GetColumn("table2id");
                    foreach (var row2 in descriptionLookup)
                    {
                        if (row.GetColumn("id") == descriptionId)
                        {
                        description = row2.GetColumn("description").ToString();
                        }
                    }
                }
            }
        }elseif (row.GetColumn("codetype" + index) == "0")
        {
            descriptionId = row.GetColumn(["codeid" +index]);
            foreach (var row2 in descriptionLookup)
            {
                if (row.GetColumn("id") == descriptionId)
                {
                description = row2.GetColumn("description").ToString();
                }
            }
        }

        subroutine.Add(manDataId.ToString(), description.ToString());
    }

ArrayData.Add(subroutine);
}

我没有尝试运行上面的代码,所以那里可能有一两个问题,但它得到了使用foreach (var row3 in idLookup). 另一种方法似乎是进行数据库查询,但这似乎比仅仅遍历内存中的内容更密集,但似乎有一种更好的方法让我错过了如何获取idtable2id不使用 foreach。

为了使它成为历史上最长的问题:) 这是我到目前为止的 SQL:

SELECT table1.id, table1.field1, table1.field2,
table2.description, fee.amt as fee FROM table2
INNER JOIN table1
ON table2.id = table1.codeid1
OR table2.id = table1.codeid2
OR table2.id = table1.codeid3
OR table2.id = table1.codeid4
OR table2.id = table1.codeid5
OR table2.id = table1.codeid6
OR table2.id = table1.codeid7
OR table2.id = table1.codeid8
OR table2.id = table1.codeid9
OR table2.id = table1.codeid10
OR table2.id = table1.codeid11
OR table2.id = table1.codeid12
OR table2.id = table1.codeid13
OR table2.id = table1.codeid14
OR table2.id = table1.codeid15
OR table2.id = table1.codeid16
OR table2.id = table1.codeid17
OR table2.id = table1.codeid18
OR table2.id = table1.codeid19
OR table2.id = table1.codeid20
INNER JOIN fee ON table2.id = fee.id
WHERE table1.codetype1 = 0
AND table1.codetype2 = 0
AND table1.codetype3 = 0
AND table1.codetype4 = 0
AND table1.codetype5 = 0
AND table1.codetype6 = 0
AND table1.codetype7 = 0
AND table1.codetype8 = 0
AND table1.codetype9 = 0
AND table1.codetype10 = 0
AND table1.codetype11 = 0
AND table1.codetype12 = 0
AND table1.codetype13 = 0
AND table1.codetype14 = 0
AND table1.codetype15 = 0
AND table1.codetype16 = 0
AND table1.codetype17 = 0
AND table1.codetype18 = 0
AND table1.codetype19 = 0
AND table1.codetype20 = 0

只要没有任何codetype具有 1 的记录,这将非常有效,否则将跳过该记录。可能不会有任何一行都codeid / codetype被填满,也不会出现codetype全盘为 1 以匹配此查询的逆查询的情况。

4

0 回答 0