-1

更新澄清

不久前我在这里发布了一个类似的问题,它使用了 Matlab(和 Matlab GUI)。

但是,现在我正在尝试做同样的事情,但通过 Windows 窗体、C# 和已填充数据的本地静态数据库文件来实现。

数据库中的数据如下:

Compound_ID    Component1    Component2    Component3    Value
int            string        string        string        int

约 24,000 行数据。

第一列“Compound_ID”是主键。接下来的三列,“Component1”、“Component2”和“Component3”,分别包含一组约 100 个可能组件中的一个组件。每个化合物由 100 个组中的 3 个不同组件组成。组件的顺序无关紧要,因此化合物是 3 个组件的组合(不同于排列)。例子:

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

等等。从这个例子中,我们知道数据库中永远不会有另一个化合物是“ag c”或其任何其他排列,因为顺序无关紧要(100 个值的列表将生成约 161,000 个 3 的组合,但几乎有 1,000,000 个 3) 的排列。

用户将在 Windows 窗体上选择一些组件(带有复选框列表或电子表格)。他们将按下表格上的按钮。该按钮将调用一个方法来查找数据库中列出的所有化合物,这些化合物可以从用户选择的组件列表中生成。此数据将显示在同一表单上的 dataGridView 中。

一种可能完成的方法(类似于我之前帖子中另一个用户描述的 Matlab 解决方案):生成 3 个逻辑数组,每列一个,其中“1”表示包含 15 个组件之一的行。将列加在一起,只有那些值为“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

像这样的东西,其中@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 回答
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 回答
-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;
    }
}

我使用 Access 是因为我们在这里不使用 SQL Server,但是您可以将 ODBC 对象换成 SQL 对象,并且它可以工作。

带有结果的 UI 屏幕截图

于 2012-07-16T21:05:49.120 回答