2

非常に複雑な SQL クエリから得られる大きな結果セットがあります。値の中にはstring、場所を表す があります (後で値の元のページの場所を特定するのに役立ちます)、int行の他の値に基づいて行ごとに計算された優先度番号である 、およびstring値を含む別の値があります。後で表示するために覚えておく必要があります。

問題は、SQL クエリが非常に複雑 (UNIONS、JOINS、およびエイリアスを使用した複雑な計算がある) であるため、その動作をいじらずに他のものを論理的に適合させることができないことです。

ただし、クエリが完了して計算が実行された後、おそらく集計関数で解決できるものが必要ですが、すべての列が他の集計関数から取得されているわけではないため、それはオプションではありません。

結果を反復処理し、値のペアをリスト (または何らかの方法で結合された 2 つの個別のリスト) に保存する方法について、私は何日も頭を悩ませてきました。ここで、1 つの値は各場所のすべての優先値の合計です。もう 1 つの値は個別の場所の値です (つまり、結果がループされるため、以前に使用された同じ場所の値を持つ別のリスト項目は作成されませんが、他のすべての値の合計が必要です。同一の場所からの優先度値)。また、結果は降順で優先度順に並べる必要があります (したがって、2 つのリストを使用する際の問題)。

例:

編集:忘れていましたが、保存された値は、SQL クエリの優先度が最も高い行の値である必要があります。

次の結果が得られた場合:

  location                      priority                               value  

--------------------------------------------------------------------------------
   page1                           1                                  some text!
   page2                           3                                  more text!
   page2                           4                               even more text!
   page3                           3                                  text again
   page3                           1                                     text
   page3                           1                              still more text!
   page4                           6                                     text

私がやりたいことができたなら、反復後に(そしてこの順序で)次のようなことを達成できるでしょう:

  location                      priority                               value  

--------------------------------------------------------------------------------
   page2                           7                               even more text!
   page4                           6                                    text
   page3                           5                                  text again
   page1                           1                                  some text!

私は研究に次ぐ研究を行ってきましたが、このジレンマの解決に近づくものは何もありません.

私が求めていることは、強力な C# 言語でさえ難しすぎるのでしょうか?

私が考えたこと:

SQL の結果をループし、各場所の繰り返しをチェックし、すべての優先度の値をまとめて加算し、これら 2 つのプラスの値を 2 つまたは 3 つの個別のリストに格納します。

それでも助けが必要な理由

ロジックがうまくいかなかったので foreach を使用できません。またfor、IEnumerable (またはDatabase.Open.Query()、インデックスによって返されるものを格納する型) にアクセスできないため、ループを使用できません (これは理にかなっています)。 、もちろん). また、優先順位で並べ替える必要がありますが、1 つのリストを他のリストと同期させることはできません。


LINQ を使用して必要なものを選択して保存する

それでも助けが必要な理由

私はLINQを(まったく!)知りません。主な理由は、ラムダ式を理解していないからです(どれだけ読んでも)。


インスタンス化されたクラスを使用して名前と値のペアを格納する

それでも助けが必要な理由

この種の並べ替えが不可能であると予想するだけでなく、WebMatrix 環境で C#.net Web ページでファイルを使用する方法を今やってい.csますが、主に静的クラスしか使用したことがなく、少し復習コースも必要です。コンストラクターとこれを適切に設定する方法について。


この機能を、すでに大規模で複雑な SQL クエリに何らかの方法で適合させる

それでも助けが必要な理由

これはおそらく私がこの機能を理想的に望んでいる場所ですが、これはオプションではないことをもう一度強調します. 集計関数を使用してみましたが、他のすべての列が集計関数から取得されたわけではないというエラーのみが表示されます。


最初のクエリの結果セットの値に基づいて別のクエリを作成する

それでも助けが必要な理由

1 つの列 (つまり、場所) だけに基づいて個別の結果を選択することはできません。


ループロジックを正しく取得でき、値を3次元配列に格納できると仮定します

それでも助けが必要な理由

配列を宣言することはできません。配列を使用する前にすべての次元がわからないからです。

4

2 に答える 2

4

あなたの投稿は、「主に静的クラスを使用している」、「クラス/オブジェクトのインスタンス化が不可能であることを期待している」など、さまざまな方法で私を驚かせました..本当に奇妙なことを言います。私はチャールズ・バベッジからの引用でしか答えることができません:

私は、そのような疑問を引き起こす可能性のあるアイデアの混乱の種類を正しく理解することができません.

とにかく..ラムダが難しいと言うように、古典的な「手動」の方法で問題を追跡しましょう。

LOCATIONS と PRIORITIES を含む ROWS のリストがあるとします。

List<DataRow> rows = .... ; // datatable, sqldatareader, whatever

あなたはあなたが必要だと言います:

  • ユニークな場所のリスト
  • 合計された優先度とペアになった場所の「リスト」

最初の目的から始めましょう。

一意の「値」のリストを収集するには、HashSet が最適です。

HashSet<string> locations = new HashSet<string>();
foreach(var row in rows)
    locations.Add( (string)rows["LOCATION"] );

それだけです。その後、locationsハッシュセットはすべての一意の場所のみを記憶します。「追加」によって要素が重複することはありません。HashSet は、その内部にあるすべての値をチェックして「一意化」します。ちょっとトリッキーなのは、ハッシュセットに[index]演算子がないことです。値を取得するには、ハッシュセットを列挙する必要があります。

foreach(string loc in locations)
{
    Console.WriteLine(loc);
}

またはそれをリストに変換/書き換えます:

List<string> locList = new List<string>(locations);
Console.WriteLine(locList[2]); // of course, assuming there were at least three..

第二の目的に行きましょう。

「論理キー」のように動作するものに関連する値のリストを収集するには、Dictionary<Key,Val>が役立つ場合があります。「値」を「キー」に保存/関連付けることができます。つまり、次のようになります。

Dictionary<string, double> dict = new Dictionary<string, double>();
dict["mamma"] = 123.45;
double d = dict["mamma"]; // d == 123.45

    dict["マンマ"] += 101; // 可能!double e = dict["マンマ"]; // d == 224.45

ただし、不明なキーから読み取ろうとすると、喜んで例外をスローする動作があります。

Dictionary<string, double> dict = new Dictionary<string, double>();
dict["mamma"] = 123.45;
double d = dict["daddy"]; // throws KeyNotBlarghException

    dict["パパ"] += 101; // もスローします! 古い/現在の値を読み取ろうとします!

そのため、まだ知らない「キー」には非常に注意する必要があります。幸いなことに、すでにキーを知っているかどうかをいつでも辞書に問い合わせることができます。

Dictionary<string, double> dict = new Dictionary<string, double>();
dict["mamma"] = 123.45;
bool knowIt = dict.ContainsKey("daddy"); // == false

したがって、不明な場合は簡単に確認して初期化できます。

Dictionary<string, double> dict = new Dictionary<string, double>();
bool knowIt = dict.ContainsKey("daddy"); // == false
if( !knowIt )
    dict["daddy"] = 5;

dict["daddy"] += 101; // now 106

それでは..場所ごとの優先順位をまとめてみましょう。

Dictionary<string, double> prioSums = new Dictionary<string, double>();
foreach(var row in rows)
{
    string location = (string)rows["LOCATION"];
    double priority  = (double)rows["PRIORITY"];

    if( ! prioSums.ContainsKey(location) )
        // make sure that dictionary knows the location
        prioSums[location] = 0.0;

    prioSums[location] += priority;
}

そして、本当に、それだけです。これで、prioSumsはすべての場所と優先順位のすべての合計を認識します。

var sss = prioSums["NewYork"];  // 9123, assuming NewYork was some location

ただし、すべての場所をハードコーディングする必要があるのはまったく役に立ちません。したがって、現在知っているキーについて辞書に問い合わせることもできます

foreach(string key in prioSums.Keys)
    Console.WriteLine(key);

すぐに使用できます:

foreach(string key in prioSums.Keys)
{
    Console.WriteLine(key);
    Console.WriteLine(prioSums[key]);
}

すべての場所とその合計を出力する必要があります。

すでに興味深いことに気付いているかもしれません: 辞書は、記憶しているキーを教えてくれます。したがって、最初の目的の HashSetは必要ありません。ディクショナリ内の優先順位を合計するだけで、場所の一意のリストを無料で取得できます。ディクショナリにそのキーを尋ねるだけです。

編集:

他にもいくつかのリクエスト (降順ソートや最上位プライオ値の検索など) があることに気付きましたが、今はそれらを残しておきます。ディクショナリを使用して優先度を収集する方法を理解していれば、同様のディクショナリを簡単に作成しDictionary<string,string>て、場所の最高ランクの値を収集できます。そして、「降順」は、値を辞書から取り出してリストとしてソートするだけで非常に簡単に実行できます..だから今はそれをスキップします..

于 2013-07-11T22:17:32.380 に答える