2012-01-15 12 views
0

私はローンを作る人のデータを保持するDBを持っています。貸付は、一人または一人の人で行うことができます。私は自分のデータベーススキーマの一部を示します。グループbyツリービュー形式

enter image description here

「Acreditadosは」「のPersonas」(人)と「Creditos」(ローン)ので、1人で複数のローンを持っている可能性があり、1つのローンは、複数の人によって作られている可能性との関係を保持します。 'Agrupaciones'は 'acreditados'(すでにローンを持っている人)と 'grupos'(グループ別ローンはグループ名を持っている)の関係を維持しています。 最後に、「movimientos」は全員の料金と支払いを維持します。

ここでの質問は、すべての支払い(movimientos)をローン(クレジット)でグループ化するためにデータベースを照会する方法です。個人のローンショー名であればグループのローンショー名グループ?すべての支払いは別の日付を持っているので、「creditos」(ローン)によって、このクエリIグループの支払いで

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 
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 
WHERE C.status = 0 
GROUP BY CR.id_credito, M.fecha_mov 
ORDER BY M.fecha_mov 

、日付ごと:

は、私はすでに次のクエリを持っています。しかし、どのように私はローンをした人の名前を取得するために、そしてグループのグループショー名によるローンであれば、「ペルソナ」(人物)テーブルにこれを参加させるのですか?実際には、これが従来のクエリで可能で、これのporpouseがグループの名前がす​​べての人と子ノードであるc#で3ビューを作成するのであれば、私はしません。個人ローンは、子なしの親ノードです。 任意の助けいただければ幸いそれはあなたの現在のスキーマに関連し、感謝

+0

「個人」ローンは、1人のメンバー(デフォルトでメンバーの名前ですか?)にグループ化し、大量の問題を保存し、他のローンを「グループ」に追加したり削除する機能を提供します。あなたがこのグループ/単一の分割を望んでいないと私を信じて、それはあなたの顔にこれより多くの時間を取得します。 –

+0

グループ名がデフォルトのメンバー名に設定された 'agrupaciones'に個人ローンを挿入すると、この分割が解決されると思いますか?しかし、threeview porpouseはどうですか?私がこれを行うと、どのように子ノードに人の情報を表示する3ビューを作ることができますか? –

+0

あなたの問題は、1つまたは2つの異なるものとして多くのもののためのローンを扱うことから来ています。ローン - >グループ - >借り手。グループ内の借り手が1人だけであれば、中間ノードをスキップできますが、ツリーを構築するときは子カウントで、クエリは同じになり、プレゼンテーションには依存しません。 –

答えて

0

おそらく、行を複製してすべての集約関数を投げ捨てる可能性がある追加のテーブルを結合することは非常に気になるでしょう。

ローンに2人が添付されていると仮定して、ローンの支払いを開始し、ローンに戻ってから、そのローンに属する人々に参加します。これで、あなたは今対処しなければならないすべてのローン支払い(各人に1つ)ごとに2つのレコードを持つようになります。

OUTER APPLYを使用してフィールドを必要なものに戻すことをお勧めします。あなたが外/クロスが適用使ったことがない場合は、単にSELECT文でサブクエリと考える:

SELECT (SELECT TOP 1 i.someColumn FROM innerTable i WHERE i.ID = t.ID) FROM someTable AS t 

ことを除いて、それ自体に参加以内です。つまり、FROM句のIN SCOPEサブクエリを使用して後で結合することができます。実際には、すべての支払いをローンのみに限定し、この他のクエリにすべての人/グループを保持するために、おそらくこれが最良の賭けです。これは、それはすでにだからOUTERは、FROM句内のテーブルの残りの部分に戻って参加する必要はありません適用されることがあるから奪う

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句のソース(テーブル)の値に基づいてクエリを実行しているという前提の下で作業します。また、APPLYクエリのエイリアスを忘れないでください(この場合はtgtpです)。

編集:ツリービュー形式にする必要があります。私は今それに取り組んでいきます。

どのような場合でも、各自のすべてのレコードも返されるように思われます。この状況では、グループ内のすべての人物に対して同じレコードが返されます。私がそれをするのが最良の方法は、人のテーブルに定期的な参加(適用の代わりに)として参加し、その後だけでtg.nombrepersonas.nombreフィールドでグループ化することです。そうすれば、ローンに添付されているすべての人物が取得されますが、グループがある場合はツリーのルートノードとして使用できるように、グループ名も返されます。

これをツリービューとして実際に作成するには、実際にそれをセットアップするために余分な作業をする必要があります。私は、使用可能な形式でクエリを取得し、LINQグループ化を使用して一緒にコンパイルすることをお勧めします。

クエリは、この方法を変更する必要があります:ISNULL(tg.nombre, tp.nombre) Nombreからtg.nombre Grupo, P.nombre Nombreに選択/グループを変更、INNER JOIN personas P on P.id_persona = A.id_personaに上記の変更で行OUTER APPLY (SELECT TOP 1 P.nombre FROM personas P WHERE P.id_persona = A.id_persona) tpを変更 。あなたのコードでは、クエリの結果を取り戻すした後、あなたのクエリを取得するには、次の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オブジェクトに変換するだけです。私は上の私の説明はそれに答えていると思うが、何が起こっているのかを正確に説明したコードを与えることができる。 (と理解しやすいです)これはまだ混乱している場合、あなたは同じことを実現するforeachを行うことができます

// 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()); 
    } 

:あなたのリストを仮定すると、これを試行し、amortListと呼ばれ、あなたのツリービューがtvLoansと呼ばれています。

+0

まずはあなたのお手伝いをしていただきありがとうございます。私は既にLINQを使用してクエリを作成し、提案したのと同じ方法で結果を得ました。私の結果は、List <_Amortizacion>に格納されます。ここで_Amortizacionには必要なフィールドがあります。 LINQを使用してそのリストを使用してツリービューの部分を作成するにはどうすればよいですか? –

+0

私の答えに再び追加されました。あなたにはいくつかのオプションがあります。これはすべてこのウィンドウで行われていたので、構文エラーが発生する可能性があります(何も識別できないはずはありません)。 – SPFiredrake

+0

パーフェクト、素晴らしい説明。これにあなたの時間を取ってくれてありがとう。 –

0

は、あなたが使用することができ、あなたの質問に答えるために:

  • LEFTはペルソナとagrupaciones
  • にacreditadosのJOIN
  • をgruposするagrupacionesを登録しよう
  • CASE文を使用すると、nombreがpersonasまたはgruposから引き出されているかどうかを調べることができます。

これをツリービューで構築する場合は、再帰的なクエリを実行してデータを取得しました。

これが役に立ちます。

+0

しかし、CASE文で評価されるブール式は何でしょうか?私はP.id_personaがTHEN \t \t WHEN G.id_grupo THEN G.nombre \t END 、CR.id_creditoをP.nombres WHEN SELECT 'ノンブル' = \t CASE \t \t \tのようなものを試してみました...しかし、しませんでしたwork –

+0

あなたはNULLをチェックします。 'いつP.id_personaがNULLでないのですか?P.nombres ........ ' – user1135379

関連する問題