一个筛选查询的问题

Mr-Jee 2009-04-27 11:19:35
客户需要一个查询功能,通过对几个字段条件进行查询,遇到的问题是
有a,b,c,d,e,f等字段,每个字段可以选择多种查询筛选,比如a>50 a<100 a<>140 a>200 a not in (55,67,89)等,这些关系可以进行与或选择。
如何确定优先关系,因为与或的先后顺序会有影响的。

...全文
257 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
wartim 2009-04-27
  • 打赏
  • 举报
回复
不复杂的,我在delphi和c#里的高级查询都是这么做的,很通用的一个模块,可以做得和具体业务无关,什么项目都能用,第一列是通过配置自动填充的一个combox列,选一下后,如果是金额列,还可以判断只能输入数字,第2列也是动态生成和填充的combox列,选一下就行了,AND和OR也是combox列选,一切都是通过数据库的表字段配置来的
混用就麻烦点了,要考虑优先级,最后加一列,就成这样

姓名 等于 张三 AND (
出生日期 大于 1980-1-1 OR
出生日期 小于 1986-1-1 )AND
姓名 等于 李四


而且如果选择的比如是姓名,也就是字符串,自动第2列填充等于、不等于、相似,而如果是日期。自动填充的是从、到等一些人性化的词语
烈火蜓蜻 2009-04-27
  • 打赏
  • 举报
回复
关于问题,看你的条件是怎么描述,而不是别的问题
Mr-Jee 2009-04-27
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 wartim 的回复:]
用一个datagridview
比如

第1列 第2列 第4列 第5列
姓名 等于 张三 AND
出生日期 大于 1980-1-1 AND
出生日期 小于 1986-1-1 OR
姓名 等于 李四


not 可以用 不等于 代替
如果要()就更麻烦点,而且要多加列,不过至于搞这么复杂么,最 常用的无非是一个条件或2个条件,AND和OR混用都不多,这么复杂,客户搞这么查询语句的时间还不如分2次查,做模块前,先想想如…
[/Quote]

的确,我也想过其他的方式来实现。这个查询看似太复杂,即使实现了 给客户用也未必好用,但是客户一而再,再而三的提出要这样做,而且AND OR混用也很多,没办法,往往这些单位就是这样。我们只能尽量去满足他所要的
wartim 2009-04-27
  • 打赏
  • 举报
回复
写错了

然后构建的时候 sql="...where 2>1 "
foreach datarow
{
sql+=" AND ..... "
parameters addwithvalue...
}
wartim 2009-04-27
  • 打赏
  • 举报
回复
然后构建的时候 sql="...where 2>1 "
foreach datarow
{
sql+=.....
parameters addwithvalue...
}
wartim 2009-04-27
  • 打赏
  • 举报
回复
用一个datagridview
比如

第1列 第2列 第4列 第5列
姓名 等于 张三 AND
出生日期 大于 1980-1-1 AND
出生日期 小于 1986-1-1 OR
姓名 等于 李四


not 可以用 不等于 代替
如果要()就更麻烦点,而且要多加列,不过至于搞这么复杂么,最 常用的无非是一个条件或2个条件,AND和OR混用都不多,这么复杂,客户搞这么查询语句的时间还不如分2次查,做模块前,先想想如果这个东西你来用。你会不会用得不爽
Mr-Jee 2009-04-27
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 geaim 的回复:]
用复选框来解决。
在复选框的事件中添加代码。
[/Quote]

你的方法和我遇到问题的侧重点不太一样。这个问题我已经参考过几种方法 基本上就是拼SQL
Mr-Jee 2009-04-27
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 ximi82878 的回复:]
写个初始化的SQL语句,然后where条件为 "1=1",读条件文本框,判断是否有值,有就带到SQL语句里,没有就不管。
如果是并集的就在下拉框里写条件,如果是不同级别,多条件的,就另做一个文本框,以此类推
[/Quote]

一个文本框内的执行顺序要用户自己来明确作出回答吧。如果客户自己填写有二义性怎么办
同理多文本框之间也是如此
Mr-Jee 2009-04-27
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 zzxap 的回复:]
与或的先后顺序数据库会自动优化处理的,
not in 用left join代替
大于号等于号 不等于号,用一个下拉菜单选择,紧跟一个textbox ,然后又是下拉菜单紧跟textbox

not in 可以用一个textbox 里面输入的内容可以用空格和逗号分隔,后台自动处理成逗号分隔。
[/Quote]
老大,可能是我的需求说明的有问题,不过这个只能算是回答如何去拼接字符串,而不能去正确查询客户所要的查询。
与和或的优化和优先关系应该是两个截然不同的概念
Mr-Jee 2009-04-27
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 cpp2017 的回复:]
第一种加()号,不过这不直观.
二做成分级形式,有点类似树,最上层的优先级高,然后是下级 .....
[/Quote]

二种方式对客户的要求都蛮高的。第一种的括号肯定是客户加的
第二种和我想的有点类似,只是问题出在所谓优先级的选择上
ximi82878 2009-04-27
  • 打赏
  • 举报
回复
写个初始化的SQL语句,然后where条件为 "1=1",读条件文本框,判断是否有值,有就带到SQL语句里,没有就不管。
如果是并集的就在下拉框里写条件,如果是不同级别,多条件的,就另做一个文本框,以此类推
zzxap 2009-04-27
  • 打赏
  • 举报
回复
与或的先后顺序数据库会自动优化处理的,
not in 用left join代替
大于号等于号 不等于号,用一个下拉菜单选择,紧跟一个textbox ,然后又是下拉菜单紧跟textbox

not in 可以用一个textbox 里面输入的内容可以用空格和逗号分隔,后台自动处理成逗号分隔。



cpp2017 2009-04-27
  • 打赏
  • 举报
回复
第一种加()号,不过这不直观.
二做成分级形式,有点类似树,最上层的优先级高,然后是下级 .....
blestcc 2009-04-27
  • 打赏
  • 举报
回复
加括號
GYXJJ 2009-04-27
  • 打赏
  • 举报
回复
帮顶!呵呵
哈哈潜伏哥 2009-04-27
  • 打赏
  • 举报
回复
用复选框来解决。
在复选框的事件中添加代码。




DGVLog.Columns.Clear();
string SQL = "Select * from SMSLog where ID > 0 ";//初始化一个SQL查询语句
if (!(CHKBOperationType.Checked || CHKBCarNumber.Checked || CHKBDate.Checked || CHKDWResult.Checked))
{
MessageBox.Show("开始查询前,请至少选择一个查询条件!", "查询提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
else
{

//if (CHKBUserName.Checked)
//{
// if (combUserName.Text == "")
// {
// MessageBox.Show("请选择或输入需要查询的用户名!", "查询提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
// return;
// }
// else
// {
// SQL += " and username = '" + combUserName.SelectedItem.ToString().Trim() + "'";
// }
//}
if (CHKBOperationType.Checked)
{
if (combOperationType.Text == "")
{
MessageBox.Show("请选择或输入需要查询的操作类型!", "查询提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
else
{
SQL += " and RecOrSend = '" + combOperationType.SelectedItem.ToString().Trim() + "'";
}
}
if (CHKBCarNumber.Checked)
{
if (combCarNumber.Text == "")
{
MessageBox.Show("请选择或输入需要查询车牌号码!", "查询提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
else
{
SQL += " and CarNumber ='" + combCarNumber.SelectedItem.ToString().Trim() + "'";
}
}
if (CHKDWResult.Checked)
{
if (ComboxDWResult.Text == "")
{
MessageBox.Show("定位结果不能为空,如果不过滤定位结果,\r请不要将其上的复选框选中!", "查询提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
//MessageBox.Show("接收手机号不能为空,如果不需要过滤其他关键字,请不要将其他关键字复选框选中!", "查询提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
else
{
SQL += " and DWResult = '" + ComboxDWResult.Text.Trim() + "'";
}
}
if (CHKBRecNumber.Checked)
{
if (TextRecNumber.Text == "")
{
MessageBox.Show("接收手机号不能为空,如果不需要过滤手机号,\r请不要将其上的复选框选中!", "查询提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
SQL += " and RecPhoneNumber like '%" + TextRecNumber.Text + "%'";
}
}
if (CHKBDate.Checked)
{
if (DTPEnd.Value.Date < DTPStart.Value.Date)
{
MessageBox.Show("开始日期不能晚于结束日期", "查询提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
else
{
SQL += "and OperationDateTime > #" + DTPStart.Value.Date + "# and OperationDateTime < #" + DTPEnd.Value.Date.AddDays(1.0) + "#";
}
}
SQL += " order by ID";
LoadDGV(SQL);
}
}
catch(Exception err)
{
Tools.ShowMessage(err.ToString(), MessageBoxIcon.Information);
}


具体思路就是,先初始化一个SQL查询语句,然后遍历所有条件,有条件的就在SQL语句后加上相应条件,没有条件的就不在SQL语句后加了。
我的程序和楼主需求一样,这是我想了很久才想到的。
Mr-Jee 2009-04-27
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 viki117 的回复:]
分段生成sql的where语句啊。。
string sqlwhere = "0=0 ";
if(a.check == true)//这里你自己看要怎么判断
sqlwhere = sqlwhere + "and a >" + 条件1;
。。。。
就怎么下去,最后把sqlwhere放到你的select语句后面就好了,
注意空格的位置。。
怕注入的话就用参数类型来执行语句,麻烦点而已,安全好
[/Quote]
。。。。。。
viki117 2009-04-27
  • 打赏
  • 举报
回复
分段生成sql的where语句啊。。
string sqlwhere = "0=0 ";
if(a.check == true)//这里你自己看要怎么判断
sqlwhere = sqlwhere + "and a >" + 条件1;
。。。。
就怎么下去,最后把sqlwhere放到你的select语句后面就好了,
注意空格的位置。。
怕注入的话就用参数类型来执行语句,麻烦点而已,安全好
wartim 2009-04-27
  • 打赏
  • 举报
回复
错了,是逻辑公式编辑器
wartim 2009-04-27
  • 打赏
  • 举报
回复
如果不混用,and列甚至可以不要
不过看你的需求,说混用挺多的,估计如果不能说服,其实不是做查询了,最好是做成一个带字段的计算公式编辑器了
加载更多回复(4)

111,126

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧