我会很关心加入额外的表,可能会重复行,从而抛出所有的聚合函数。我的意思是这样的:
假设你有两个人附加贷款,所以你从贷款支付开始,加入贷款,然后加入属于该贷款的人。您现在必须为每笔贷款付款(每个人一份)记录2条记录,您现在必须处理这些记录。
我会建议做的是使用外部应用程序将字段加入到您所需的内容中。如果您从未使用过外/交叉应用,只是把它作为一个select语句的子查询:
SELECT (SELECT TOP 1 i.someColumn FROM innerTable i WHERE i.ID = t.ID) FROM someTable AS t
除了它的内加入本身。这意味着您可以在FROM子句中使用IN SCOPE子查询来重新加入。事实上,这可能是你最好的选择,为了保持所有支付本地化为贷款,并保留所有人/组在这个其他查询。所以,你的查询会是这个样子:
SELECT CR.id_credito, SUM(M.monto) AS Monto, SUM(M.interes) AS Interes, SUM(M.iva) AS IVA, SUM(M.capital) AS Capital, M.fecha_mov, ISNULL(tg.nombre, tp.nombre) Nombre
FROM movimientos AS M
JOIN cargos AS C ON C.id_movimiento = M.id_movimiento
JOIN acreditados AS A ON A.id_acreditado = M.id_acreditado
JOIN creditos AS CR ON CR.id_credito = A.id_credito
OUTER APPLY (SELECT TOP 1 G.nombre FROM grupos G JOIN agrupaciones AG on AG.id_grupo = G.id_grupo WHERE AG.id_acreditado = A.id_acreditado) tg
OUTER APPLY (SELECT TOP 1 P.nombre FROM personas P WHERE P.id_persona = A.id_persona) tp
WHERE C.status = 0
GROUP BY CR.id_credito, M.fecha_mov, ISNULL(tg.nombre, tp.nombre)
ORDER BY M.fecha_mov
一件事夺去这是外适用不需要连接回表中的其余FROM子句,因为它已经假设您基于来自FROM子句源(表)的其余部分的值进行查询。此外,不要忘记别名您的APPLY查询(在这种情况下,它是tg
和tp
)。
编辑:刚才注意到需要树视图格式。我现在就解决这个问题。
看来,无论如何,你希望每个人的所有记录也能被返回。在这种情况下,您希望为组内的所有人返回相同的记录。我认为最好的办法是以普通加入的方式回到人员表格(而不是应用),然后按tg.nombre
和personas.nombre
字段进行分组。这样,您仍然可以获得每个附加到贷款的人,但您也可以返回组名,以便如果有组,则可以将其用作树中的根节点。
至于实际创建这个树视图,你将不得不做一些额外的工作,以实际上得到它的设置。我建议的是以可用格式获取查询,并使用LINQ分组将它们一起编译。
查询,然后将需要改变这样: 在上面的变化而变化的线OUTER APPLY (SELECT TOP 1 P.nombre FROM personas P WHERE P.id_persona = A.id_persona) tp
到INNER JOIN personas P on P.id_persona = A.id_persona
,改变选择/分组从ISNULL(tg.nombre, tp.nombre) Nombre
到tg.nombre Grupo, P.nombre Nombre
。在代码中,取回您的查询结果后,请使用以下LINQ语句获取查询(假设它至少.NET 3.5):
// Assume the query results are in dtLoanPayments strongly typed datatable.
// Also assume we have a TreeView called tvLoans
dtLoanPayments.AsEnumerable().GroupBy(tr => tr.Grupo).ToList().ForEach(tr =>
{
(tr.Key == null ? tvLoans.Nodes : tvLoans.Nodes.Add(tr.Key)).AddRange
(tr.Select(ti => { TreeNode tempNode = new TreeNode(ti.Nombre); tempNode.Tag = ti; return tempNode; }).ToArray());
});
再次,它真的只是取决于你如何希望他们显示。如果你想进一步分组,那么你需要在内部tr.Select
前做另一个GroupBy,因此它会是tr.GroupBy(ti => ti.Personas).Select
,你必须为每个贷款支付记录创建另一个TreeNode。在这些类型的情况下,请记住保持显示和数据逻辑分离通常要容易得多。在查询方面,只要确保你找回的数据是正确的,然后在应用程序代码中处理格式。
编辑:要回答你的评论问题,添加一些更多的代码。 这只是将您的项目列表转换为正确嵌套的TreeNode对象的问题。我想我上面的解释可以回答这个问题,但我可以给你解释代码的解释。假设你的列表被称为amortList
和您的TreeView被称为tvLoans
,那就试试这个:
// First, group by group name. If it's null (meaning no group), then it will just be
// the person's name. Doing ToList() after grouping so we can do a ForEach.
amortList.GroupBy(tr => string.IsNullOrEmpty(tr.Grupo) ? tvLoans : tvLoans.Add(tr.Grupo)).ToList()
.ForEach(tr =>
// This gives us the node we'll be adding each record to as the key. Now all
// we need to do is add all loan records to the node, grouping by person
{
tr.Key.Nodes.AddRange(
// Group by person's name first
tr.GroupBy(ti => new TreeNode(ti.Nombre))
// Then transform into each node (loan payment, etc) and add to the person node.
.Select(ti =>
{
ti.Key.Nodes.AddRange(
ti.Select(tn => new TreeNode(/*Use whatever field here to display.*/).ToArray());
return ti.Key; // Return TreeNode.
}).ToArray());
}
如果这仍然是混乱的,你可以做,完成同样的事情(和更容易理解)一个foreach。
foreach(_Amortizacion amNode in amortList)
{
// Using Null Coalescing to create the node if it doesn't exist.
// First check if group is null. If it isn't, try to pull the node and create it if it doesn't exist.
TreeNodeCollection workingNode = !string.IsNullOrEmpty(amNode.Grupo) ?
(tvLoans.Nodes[amNode.Grupo] ?? tvLoans.Nodes.Add(amNode.Grupo)).Nodes :
tvLoans.Nodes;
// At this point, workingNode is the NodeCollection we'll be adding the person to. Creating if doesn't exist.
workingNode = (workingNode[amNode.Personas] ?? workingNode.Add(amNode.Personas)).Nodes;
// Now we're adding the actual loan record to the person Node.
workingNode.Add(new TreeNode(/* This is what will show up in TreeView. */) { Tag = amNode, Name = /* Specify a key here, in case you want to search. */ });
}
做一个“个人”贷款一组只有一个成员(默认为成员的名字吗?),节省了群众的问题,并为您提供设施,以债权人的其他添加和删除到“组”。相信我你不想要这个群体/单独的分裂,它会比这个更多的时间在你的脸上。 – 2012-01-15 18:55:35
因此,您认为在'agrupaciones'中插入个人贷款时,将组名设置为默认成员的名称可以解决这个问题?但是三看门人呢?如果我这样做,我怎样才能在三维视图中显示子节点中的人员信息? – 2012-01-15 19:18:48
你的问题来自处理贷款的一个或多个作为两个不同的事情。贷款 - >小组 - >借款人。如果组中只有一个借用者,那么您可以跳过中间节点,但这是构建树时的子数,您的查询将是相同的,并且与演示不可知。 – 2012-01-16 00:37:12