SQL 多条件查询

网上有不少人提出过类似的问题:“看到有人写了WHERE 1=1这样的SQL,到底是什么意思?”。其实使用这种用法的开发人员一般都是在使用动态组装的SQL。让我们想像如下的场景:用户要求提供一个灵活的查询界面来根据各种复杂的条件来查询员工信息,界面如下图:

界面中列出了四个查询条件,包括按工号查询、按姓名查询、按年龄查询以及按工资查询,每个查询条件前都有一个复选框,如果复选框被选中,则表示将其做为一个过滤条件。比如上图就表示“检索工号介于DEV001和DEV008之间、姓名中含有J并且工资介于3000元到6000元的员工信息”。如果不选中姓名前的复选框,比如下图表示“检索工号介于DEV001和DEV008之间并且工资介于3000元到6000元的员工信息”:

如果将所有的复选框都不选中,则表示表示“检索所有员工信息”,比如下图:

这里的数据检索与前面的数据检索都不一样,因为前边例子中的数据检索的过滤条件都是确定的,而这里的过滤条件则随着用户设置的不同而有变化,这时就要根据用户的设置来动态组装SQL了。当不选中年龄前的复选框的时候要使用下面的SQL语句:

SELECT * FROM T_Employee
WHERE FNumber BETWEEN ‘DEV001‘ AND ‘DEV008‘
AND FName LIKE ‘%J%‘
AND FSalary BETWEEN 3000 AND 6000

而如果不选中姓名和年龄前的复选框的时候就要使用下面的SQL语句:

SELECT * FROM T_Employee
WHERE FNumber BETWEEN ‘DEV001‘ AND ‘DEV008‘
AND FSalary BETWEEN 3000 AND 6000

而如果将所有的复选框都不选中的时候就要使用下面的SQL语句:

SELECT * FROM T_Employee

要实现这种动态的SQL语句拼装,我们可以在宿主语言中建立一个字符串,然后逐个判断各个复选框是否选中来向这个字符串中添加SQL语句片段。这里有一个问题就是当有复选框被选中的时候SQL语句是含有WHERE子句的, 而当所有的复选框都没有被选中的时候就没有WHERE子句了,因此在添加每一个过滤条件判断的时候都要判断是否已经存在WHERE语句了,如果没有WHERE语句则添加WHERE语句。 在判断每一个复选框的时候都要去判断, 这使得用起来非常麻烦,“聪明的程序员是会偷懒的程序员”,因此开发人员想到了一个捷径:为SQL语句指定一个永远为真的条件语句(比如“1=1”),这样就不用考虑WHERE语句是否存在的问题了。伪代码如下:

String sql = " SELECT * FROM T_Employee WHERE 1=1";
if(工号复选框选中)
{
sql.appendLine("AND FNumber BETWEEN ‘"+工号文本框1内容+"‘ AND ‘"+工号文本框2内容+"‘");
}
if(姓名复选框选中)
{
sql.appendLine("AND FName LIKE ‘%"+姓名文本框内容+"%‘");
}
if(年龄复选框选中)
{
sql.appendLine("AND FAge BETWEEN "+年龄文本框1内容+" AND "+年龄文本框2内容);
}
executeSQL(sql);

这样如果不选中姓名和年龄前的复选框的时候就会执行下面的SQL语句:

SELECT * FROM T_Employee WHERE 1=1
AND FNumber BETWEEN ‘DEV001‘ AND ‘DEV008‘
AND FSalary BETWEEN 3000 AND 6000

而如果将所有的复选框都不选中的时候就会执行下面的SQL语句:

SELECT * FROM T_Employee WHERE 1=1

这看似非常优美的解决了问题,殊不知这样很可能会造成非常大的性能损失,因为使用添加了“1=1”的过滤条件以后数据库系统就无法使用索引等查询优化策略,数据库系统将会被迫对每行数据进行扫描(也就是全表扫描)以比较此行是否满足过滤条件,当表中数据量比较大的时候查询速度会非常慢。因此如果数据检索对性能有比较高的要求就不要使用这种“简便”的方式。下面给出一种参考实现,伪代码如下:

private void doQuery()
{
Bool hasWhere = false;
StringBuilder sql = new StringBuilder(" SELECT * FROM T_Employee");
if(工号复选框选中)
{
hasWhere = appendWhereIfNeed(sql, hasWhere);
sql.appendLine("FNumber BETWEEN ‘"+工号文本框1内容+"‘ AND ‘"+工号文本框2内容+"‘");
}
if(姓名复选框选中)
{
hasWhere = appendWhereIfNeed(sql, hasWhere);
sql.appendLine("FName LIKE ‘%"+姓名文本框内容+"%‘");
}
if(年龄复选框选中)
{
hasWhere = appendWhereIfNeed(sql, hasWhere);
sql.appendLine("FAge BETWEEN "+年龄文本框1内容+" AND "+年龄文本框2内容);
}
executeSQL(sql);
}
private Bool appendWhereIfNeed(StringBuilder sql,Bool hasWhere)
{
if(hasWhere==false)
{
sql. appendLine("WHERE");
}
else
{
sql. appendLine("AND");
}
}

以上内容由博主摘自《程序员的SQL金典》。

模糊查询时:

[java] view plaincopyprint?

  1. String name = request.getParameter("name");  //姓名
  2. String rank= request.getParameter("age");  //年龄
  3. String address= request.getParameter("address");  //地址
  4. String sql = "select * from  student where 1=1 ";
  5. if(name!=null && !name.equals("")){
  6. sql += "t.name like ‘%"+name+"%‘";
  7. }
  8. if(rank!=null && !rank.equals("")){
  9. sql += "t.age like ‘%"+age+"%‘";
  10. }
  11. if(address!=null && !address.equals("")){
  12. sql += "t.address like ‘%"+address+"%‘";
  13. }
时间: 2024-07-29 18:05:58

SQL 多条件查询的相关文章

Linq to Sql 多条件查询

Linq To Sql 多条件查询 string proName = this.txtName.Text.Trim();string lowPrice = this.txtLowPrice.Text.Trim();string highPrice = this.txtHighPrice.Text.Trim(); decimal? lowPrice1 = null, highPrice1 = null;if (!string.IsNullOrEmpty(lowPrice)){        low

C# SQL多条件查询拼接技巧

本文转载:http://blog.csdn.net/limlimlim/article/details/8638080 #region 多条件搜索时,使用List集合来拼接条件(拼接Sql) StringBuilder sql = new StringBuilder("select * from PhoneNum"); List<string> wheres = new List<string>(); if (cboGroup.SelectedIndex !=

SQL多条件查询安全高效比较

ALTER PROCEDURE _tmp @ID VARCHAR(50), @PN VARCHAR(50), @Type INT AS BEGIN /********************************** -- 功能:多条件查询性能 _tmp 'K3G8KG6NN94SBBS0','K7F7FF',0 **********************************/ PRINT '测试数据条数500W' set nocount ON DECLARE @time DATETIM

Webform中linq to sql多条件查询(小练习)

多条件查询:逐条判断,从第一个条件开始判断,如果满足,取出放入集合,再从集合中查询第二个条件... aspx代码: 1 <body> 2 <form id="form1" runat="server"> 3 4 <br /> 5 <asp:Label ID="Label1" runat="server" Text="关键字:"></asp:Label&g

qt sql多重条件查询简便方法

转载请注明出处:http://www.cnblogs.com/dachen408/p/7457312.html 程序设计过程中,经常要涉及到查询,并且有很多条件,且条件可为空,如果逐个判断,会有很多情况,解决方案: QSqlQuery query(m_db); QString province = QString::fromLocal8Bit("广东"); QString city = ""; QString null = ""; QString

SQL 时间条件查询

to_date()使用 select * from table t where t.time >= to_date(aaaa,'yyyy-mm-dd hh24:mm:ss') and t.time<to_date(bbbb,'yyyy-mm-dd hh24:mm:ss') aaaa,bbbb是字符串类型 比如:aaaa = '2018-04-19 00:00:00' bbbb = '2018-04-20 00:00:00' to_date()中yyyy-mm-dd hh24:mm:ss 意思把

C# SQL 多条件查询技巧

#region 多条件搜索时,使用List集合来拼接条件(拼接Sql) StringBuilder sql = new StringBuilder("select * from PhoneNum");            List<string> wheres = new List<string>();            if (cboGroup.SelectedIndex != 0)            {                wheres.

sql 多条件查询 拼接字符串 改成 普通查询格式

set ANSI_NULLS ON set QUOTED_IDENTIFIER ON go ALTER PROC [dbo].[usp_SRV_CheckServiceDemandOrder] @AInsNO NVARCHAR(50) =null,--必填 @ACompanyName NVARCHAR(50) = null,--必填 @ADepartmentName NVARCHAR(50) = null, @AName NVARCHAR(50) = null, --必填 @ApplicantI

SQL多条件查询

SELECT a.tel,a.business_code,b.name AS business_name,a.register_time FROM T_RED_USER a LEFT JOIN T_Product_Spec b ON a.business_code=b.code where a.tel LIKE CONCAT(?,'%') AND (IF(?='', 1=1, IFNULL(a.business_code,'')=?) OR a.business_code IS NULL ) O