更新澄清
我在使用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查询)相对较新,所以请原谅我的无知。如果能更好地利用每个人的时间,请向我指出一些解释。
答案 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 query和GrayFox374'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对象并且它可以正常工作。