搜索SQL数据库并返回其列包含特定值的行

时间:2012-07-16 20:55:52

标签: c# sql-server database search

更新澄清

我在使用Matlab(和Matlab GUI)的found here前后发布了一个类似的问题。

但是,现在我正在尝试做同样的事情,但是通过Windows Form,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

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

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

可能做的一种方式(类似于我之前的帖子中另一个用户描述的Matlab解决方案):生成3个逻辑数组,每列一个,其中“1”表示包含15个组件之一的行。将列添加到一起,只有那些值为“3”的行才是我要查找的行。然后构建一个包含这些行的新表,并在datagridview中显示。有关此代码外观的任何提示都会有所帮助。

我将尝试提供一些已经提供的解决方案。这将涉及找出一种从C#调用SQL查询的方法,我被告知我可以查找,并且已经提供了一个示例。

感谢大家的帮助。这是一个独立的项目,出于好奇,所以这不是严肃的事情,我只是想弄明白。我对C#(以及SQL查询)相对较新,所以请原谅我的无知。如果能更好地利用每个人的时间,请向我指出一些解释。

4 个答案:

答案 0 :(得分: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

答案 1 :(得分: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解决方案不同,这将确保组合的唯一性

答案 2 :(得分:0)

以下是最终完成我需要的代码。它是LittleBobbyTables's SQL queryGrayFox374's C# code的组合,用于实现该查询。我会赞成你们两个,但显然我还没有影响力呢!

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;
    }
}

答案 3 :(得分:-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 ScreenShot with Results