-1

明確化のために更新

Matlab(およびMatlab GUI)を使用した同様の質問を投稿しました。

ただし、今は同じことをしようとしていますが、Windows フォーム、C#、およびデータが既に入力されているローカルの静的データベース ファイルを介して実装されています。

データベース内のデータは次のとおりです。

Compound_ID    Component1    Component2    Component3    Value
int            string        string        string        int

~24,000 行のデータで。

最初の列「Compound_ID」は主キーです。次の 3 つの列、"Component1"、"Component2"、および "Component3" には、100 個までの可能なコンポーネントのセットからそれぞれ 1 つのコンポーネントが含まれています。各化合物は、100 個のセットから 3 つの異なるコンポーネントで構成されています。コンポーネントの順序は重要ではないため、化合物は 3 つのコンポーネントの組み合わせ (順列とは異なります) です。例:

Compound_ID    Component1    Component2    Component3    Value
1456           a            b              c             10
1457           a            b              m             50
1458           a            c              g             25

など。この例から、DB 内に「ag c」またはその他の順列である別の化合物が存在しないことがわかります。しかし、3のほぼ1,000,000の順列)。

ユーザーは、Windows フォームで (チェックボックスのリストまたはスプレッドシートを使用して) いくつかのコンポーネントを選択します。彼らはフォームのボタンを押します。ボタンは、ユーザーが選択したコンポーネントのリストから作成できる、データベースにリストされているすべての化合物を検索するメソッドを呼び出します。このデータは、同じフォームの dataGridView に表示されます。

1 つの方法 (以前の投稿で別のユーザーが説明した Matlab ソリューションに似ています): 3 つの論理配列を生成します。各列に 1 つずつ、「1」は 15 のコンポーネントの 1 つを含む行を表します。列を一緒に追加すると、値が「3」の行だけが探している行になります。次に、それらの行を含む新しいテーブルを作成し、datagridview に表示します。このコードがどのように見えるかについてのヒントは役に立ちます。

すでに提供されているソリューションのいくつかを試してみます。これには、C# から SQL クエリを呼び出す方法を考え出すことが含まれます。これは検索できるとのことで、例は既に提供されています。

ご協力いただきありがとうございます。これは好奇心から生まれた完全に独立したプロジェクトなので、深刻なビジネスではありません。私は比較的 C# (および間違いなく SQL クエリ) に慣れていないため、無知であることをお許しください。それがみんなの時間をより有効に活用できるなら、少し説明のある情報源を教えてください。

4

4 に答える 4

2
Select ct.*
From costtable ct
Where ct.Col1 <> ct.Col2 and ct.Col2 <> ct.Col3 and
ct.Col1 in ('Test1', 'Test2', 'Test3') and
ct.Col2 in ('Test1', 'Test2', 'Test3') and
ct.Col3 in ('Test1', 'Test2', 'Test3')

あなたのユースケースについてはよくわかりませんが、重複するコンポーネントは可能ですか? 同じ値を持つ Col1 と Col2 のように?

これがあなたが遊ぶことができるSqlFiddleです: http://sqlfiddle.com/#!3/46944/1/0

于 2012-07-16T21:04:03.770 に答える
0

これが、私が必要としていたことを最終的に実行したコードです。これは、LittleBobbyTables の SQL クエリと、そのクエリを実装するための GrayFox374 の C# コードの組み合わせです。私はあなたの両方に賛成票を投じますが、明らかに私にはまだそれを行う力がありません!

class Program
{
    static void Main(string[] args)
    {
        List<string> components = new List<string>();
        components.Add("Ing1");
        components.Add("Ing2");
        components.Add("Ing3");
        components.Add("Ing5");
        components.Add("Ing9");


        StringBuilder sb1 = new StringBuilder();
        sb1.Append("(");

        foreach (string s in components)
        {
            string stemp = "'" + s + "'" + ",";
            sb1.Append(stemp);
        }

        int start = sb1.ToString().Length - 2;

        sb1.Replace(",", ")", start, 2);

        List<Result> results = new List<Result>();

        SqlConnection con = new SqlConnection("Data Source=.\\SQLEXPRESS;AttachDbFilename=C:\\dbTestCSV.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True");
        StringBuilder sb = new StringBuilder();
        sb.Append("SELECT [Numbers], [Col1], [Col2], [Col3], [Col4], [Col5]");
        sb.Append("FROM Table1 ");
        sb.Append("WHERE [Col1] IN ");
        sb.Append(sb1.ToString());
        sb.Append(" AND [Col2] IN ");
        sb.Append(sb1.ToString());
        sb.Append(" AND [Col3] IN ");
        sb.Append(sb1.ToString());

        SqlCommand cmd = new SqlCommand(sb.ToString(), con);
        try
        {
            con.Open();
            cmd.CommandType = System.Data.CommandType.Text;

            SqlDataReader dr = cmd.ExecuteReader();
            if (dr.HasRows)
            {
                while (dr.Read())
                {
                    results.Add(new Result(Convert.ToInt32(dr[0].ToString()), dr[1].ToString(), dr[2].ToString(), dr[3].ToString(), dr[4].ToString(), dr[5].ToString()));
                }
            }
            dr.Close();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message.ToString());
        }
        finally
        {
            con.Close();
        }


        foreach (Result res1 in results)
        {
            Console.WriteLine(res1.PK.ToString());
        }
        Console.ReadLine();
        //process/present results at this point

    }


}

public class Result
{
    public int PK { get; set; }
    public string Col1 { get; set; }
    public string Col2 { get; set; }
    public string Col3 { get; set; }
    public string Col4 { get; set; }
    public string Col5 { get; set; }

    public Result(int pk, string col1, string col2, string col3, string col4, string col5)
    {
        PK = pk; Col1 = col1; Col2 = col2; Col3 = col3; Col4 = col4; Col5 = col5;
    }
}
于 2012-07-17T18:37:38.050 に答える
0

@a、@b、@c が求める値であるこのようなもの

select 
*
from
table
where
(
case col1 when @a then 1 when @b then 2 when @c then 4 else 0 end
+ case col2 when @a then 1 when @b then 2 when @c then 4 else 0 end
+ case col3 when @a then 1 when @b then 2 when @c then 4 else 0 end
      ) = 7

単純なソリューションとは異なりIN、これにより組み合わせの一意性が保証されます

于 2012-07-16T21:04:46.513 に答える
-2

これだと思います:

アップデート

データベース テーブルの値

PKID    Col1        Col2        Col3        Cost 
1   Helium      Oxygen      Nitrogen    10
2   Hydrogen    Chlorine    Sodium      10 
3   Chlorine    Sodium      Gold        10
4   Hydrogen    Carbon      Potassium   10 
5   Carbon      Silicon     Boron       10
6   Uranium     Cesium      Plutonium   10 
7   Titanium    Iodine      Fluorine    10
8   Helium      Neon        Argon       10 
9   Krypton     Xenon       Radon       10
10  Barium      Chromium    Calcium     10 
11  Helium      Lithium     Sodium      10

したがって、ヘリウム、酸素、窒素、バリウム、クロム、カルシウム、ウランを選択すると、PKID が 1 と 10 の行が取得されます。それだけです。右?

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void btnFind_Click(object sender, EventArgs e)
    {            
        List<Component> results = new List<Component>();

        foreach (object itemChecked in checkedListBox1.CheckedItems)
        {
            var cn = new OdbcConnection(@"Driver={Microsoft Access Driver (*.mdb)};Dbq=C:\elements.mdb;Uid=Admin;Pwd=;");
            StringBuilder sb = new StringBuilder();
            sb.Append("SELECT [PKID], [Col1], [Col2], [Col3], [Cost] ");
            sb.Append("FROM components ");
            sb.Append("WHERE ? IN (Col1, Col2, Col3) ");
            var cm = new OdbcCommand(sb.ToString(), cn);
            try
            {
                cn.Open();
                cm.CommandType = System.Data.CommandType.Text;
                cm.Parameters.AddWithValue("?", itemChecked.ToString());
                OdbcDataReader dr = cm.ExecuteReader();
                if (dr.HasRows)
                {
                    while (dr.Read())
                    {
                        var comp = new Component(Convert.ToInt32(dr[0].ToString()),
                            dr[1].ToString(), dr[2].ToString(), dr[3].ToString(), Convert.ToInt32(dr[4].ToString()));

                        Component r = results.Find(
                            delegate(Component c)
                            {
                                return c.CompoundID == Convert.ToInt32(dr[0].ToString());
                            }
                            );
                        if (r != null)
                        {
                            //update the frequency
                            var obj = results.FirstOrDefault(x => x.CompoundID == comp.CompoundID);
                            if (obj != null) obj.Frequency++;
                        }
                        else { results.Add(comp); }
                    }
                }
                dr.Close();
            }
            catch (Exception ex) { Console.WriteLine(ex.Message); }
            finally { cn.Close(); }
        }

        //process/present results at this point
        //for each result in list with freq >= 3, output to grid
        IEnumerable<Component> rowsWithThreeHits = results.Where(cFreq => int.Equals(cFreq.Frequency, 3))
            .Select(x => new Component { CompoundID = x.CompoundID, Component1 = x.Component1, 
                Component2 = x.Component2, Component3 = x.Component3, CompoundValue = x.CompoundValue });
        List<Component> final = new List<Component>(rowsWithThreeHits);
        dataGridView1.DataSource = final;
    }        
}

public class Component
{
    public int CompoundID { get; set; }
    public string Component1 { get; set; }
    public string Component2 { get; set; }
    public string Component3 { get; set; }
    public int CompoundValue { get; set; }
    public int Frequency { get; set; }

    public Component() {}

    public Component(int compoundID, string component1, string component2, string component3, int compoundValue)
    {
        CompoundID = compoundID; 
        Component1 = component1;
        Component2 = component2;
        Component3 = component3;
        CompoundValue = compoundValue;
        Frequency = 1;
    }
}

ここでは SQL Server を使用していないため、Access を使用しましたが、ODBC オブジェクトを SQL オブジェクトに置き換えることができ、機能します。

結果付きの UI スクリーンショット

于 2012-07-16T21:05:49.120 に答える