我想做一个复合查询,请教如何实现./****
表名:news 表名:news_cate
news_id 编号 newscate_id
news_title 标题 news_cate_title
news_info 信息
news_cid 类别
news_date 日期 (Y-m-d H:i:s)
*****/我希望实现
新闻标题news_title 的 like 查询 news_title like '%search_info%'
新闻内容 news_info 单选 为空 ,不为空查询 news_info is null , news_info is not null
新闻类别查询 复选 {假设类别为:1 实时新闻,2 历史事件 3专题报道} 当复选 1 3 时 (news_cid = 1 or news_cid = 3)
日期开始时间
日期结束时间设定也就是说,
当我标题搜索 “测试“ 内容 单选选 为空 ,类别复选选中 2 历史事件 3 专题报道后。 开始时间填写 2010-4-1 结束时间填写 2010-5-1
查询后 sql 语句为
select * from news where news_title like '%测试%' and news_info is null and news_date > '2010-4-1' and news_date < '2010-5-1'问题一: 请问这个复合查询,如何能封装成可复用的。 我想做一个复合查询,请教如何实现./****
表名:news 表名:news_cate
news_id 编号 newscate_id
news_title 标题 news_cate_title
news_info 信息
news_cid 类别
news_date 日期 (Y-m-d H:i:s)
*****/我希望实现
新闻标题news_title 的 like 查询 news_title like '%search_info%'
新闻内容 news_info 单选 为空 ,不为空查询 news_info is null , news_info is not null
新闻类别查询 复选 {假设类别为:1 实时新闻,2 历史事件 3专题报道} 当复选 1 3 时 (news_cid = 1 or news_cid = 3)
日期开始时间
日期结束时间设定也就是说,
当我标题搜索 “测试“ 内容 单选选 为空 ,类别复选选中 2 历史事件 3 专题报道后。 开始时间填写 2010-4-1 结束时间填写 2010-5-1
查询后 sql 语句为
select * from news where news_title like '%测试%' and news_info is null and news_date > '2010-4-1' and news_date < '2010-5-1'问题一: 请问这个复合查询,如何能封装成可复用的。例如能通过很方便的配置 news_title 的查询规则变一下,变为 news_title = '测试'
问题二: 查询完了后,数据很多时,会产生分页。 假设有五页结果,当我点第三页时,我希望查询条件还能保留问题二: 查询完了后,数据很多时,会产生分页。 假设有五页结果,当我点第三页时,我希望查询条件还能保留
表名:news 表名:news_cate
news_id 编号 newscate_id
news_title 标题 news_cate_title
news_info 信息
news_cid 类别
news_date 日期 (Y-m-d H:i:s)
*****/我希望实现
新闻标题news_title 的 like 查询 news_title like '%search_info%'
新闻内容 news_info 单选 为空 ,不为空查询 news_info is null , news_info is not null
新闻类别查询 复选 {假设类别为:1 实时新闻,2 历史事件 3专题报道} 当复选 1 3 时 (news_cid = 1 or news_cid = 3)
日期开始时间
日期结束时间设定也就是说,
当我标题搜索 “测试“ 内容 单选选 为空 ,类别复选选中 2 历史事件 3 专题报道后。 开始时间填写 2010-4-1 结束时间填写 2010-5-1
查询后 sql 语句为
select * from news where news_title like '%测试%' and news_info is null and news_date > '2010-4-1' and news_date < '2010-5-1'问题一: 请问这个复合查询,如何能封装成可复用的。 我想做一个复合查询,请教如何实现./****
表名:news 表名:news_cate
news_id 编号 newscate_id
news_title 标题 news_cate_title
news_info 信息
news_cid 类别
news_date 日期 (Y-m-d H:i:s)
*****/我希望实现
新闻标题news_title 的 like 查询 news_title like '%search_info%'
新闻内容 news_info 单选 为空 ,不为空查询 news_info is null , news_info is not null
新闻类别查询 复选 {假设类别为:1 实时新闻,2 历史事件 3专题报道} 当复选 1 3 时 (news_cid = 1 or news_cid = 3)
日期开始时间
日期结束时间设定也就是说,
当我标题搜索 “测试“ 内容 单选选 为空 ,类别复选选中 2 历史事件 3 专题报道后。 开始时间填写 2010-4-1 结束时间填写 2010-5-1
查询后 sql 语句为
select * from news where news_title like '%测试%' and news_info is null and news_date > '2010-4-1' and news_date < '2010-5-1'问题一: 请问这个复合查询,如何能封装成可复用的。例如能通过很方便的配置 news_title 的查询规则变一下,变为 news_title = '测试'
问题二: 查询完了后,数据很多时,会产生分页。 假设有五页结果,当我点第三页时,我希望查询条件还能保留问题二: 查询完了后,数据很多时,会产生分页。 假设有五页结果,当我点第三页时,我希望查询条件还能保留
/*********
* 帶參數的查詢.
*********/
//餐廳區域
$layout_id=isset($_GET["layout_id"])?intval($_GET["layout_id"]):'';
$table_state=isset($_GET["table_state"]) && intval($_GET["table_state"])>0?intval($_GET["table_state"]):'';
$where="where 1";
$where.=!empty($layout_id)?" AND table_layout_id=$layout_id":'';
$where.=!empty($table_state)?" AND table_state=$table_state":''; $sql_table="SELECT t.table_id,t.opentable_id,t.table_number,t.table_name,t.table_layout_id,t.table_room_layout_id,t.table_sum,t.table_state,l.layout_name FROM `tables` as t left join layouts l on t.table_layout_id=l.layout_id $where order by t.table_id asc";
// echo $sql_table;
// $hasInfo : 传入news_info是否为空
//$ids : 想要获得新闻 ids
//return 查询的结果集
function getRecords($hasInfo,$ids,$timeFrom,$timeTo ){
$con = news_info . ($hasTitle ? 'is not null ' : 'is null') ;
$con .= " AND news_date > $timeFrom AND news_date < $timeTo ";
$sql = "select * from news where news_id IN ($ids) AND $con ";
//执行查询
//return 查询结果
}
由于查询条件需要用户输入,所以封装参数必须自行处理.
问题2:
写个分页类,共多少记录,每页多少记录,可以求出当前页的记录数.
<?php
function makeSql($_layout_id, $_table_state, $value=null) {
$layout_id=isset($_layout_id)?intval($_layout_id):$value;
$table_state=isset($_table_state) && intval($_table_state)>0?intval($_table_state):$value;
$where="where 1";
$where.=!empty($layout_id)?" AND table_layout_id=$layout_id":'';
$where.=!empty($table_state)?" AND table_state=$table_state":'';
$sql_table="SELECT t.table_id,t.opentable_id,t.table_number,t.table_name,t.table_layout_id,t.table_room_layout_id,t.table_sum,t.table_state,l.layout_name FROM `tables` as t left join layouts l on t.table_layout_id=l.layout_id $where order by t.table_id asc";
return $sql_table;
}
?>
function makeSql($where,$table)
{
$sql = "select * from table ";
if($isset($where )&& sizeof($where)) {
$sql .= "where 1=1";
}
foreach($where as $val)
{
$sql .= "&& $val";
}
return $sql;
}
这看来看去,只是一个普通的把查询条件和表名生成sql 语句的函数。
请问楼上,何来接口之说,如果真有接口,具体是怎么个接法。感觉楼上的回答很缥缈,难以理解,望回答的实在点。
1 表单提交后 能通过表单的内容自动的生成sql语句,并查询相应的数据.
2 通过点击分页,也能生成sql 语句,并且记录了之前表单的查询结果。那这种情况下,楼主希望有这样一种代码。 $myList = new xList();
$myList->setTable($this->tableName);
$myList->setIQuery(new adminIQuery());
list($data["pager"],$data['rows']) = $myList->get(); //获取数据
//当设置好所对应的表格(model) ,
//Iquery 接口。[将post 或querystring 的参数,生成查询条件,并得到用于拼值QueryString 的参数]
$this->load->view('admin/'.$this->tableName.'/index', $data);
通过上述代码,就能把post 的值,或get 的QueryString 生成相应的查询语句,并查询出列表数据,和分页栏数据,然后交由视图合成界面。
但他们给出的代码不能太过简单。
如果有很多情况都不知道如何去处理,
例如是复选情况下的搜索,怎么去解决,
如果搜索的条件是is null 如何去处理,
如果我需要的是复合查询更极端的例子呢? 例如,我希望查询 其中一个字段 等于另外两个字段的合的例子。还有个令我很头痛的问题,一直没怎么想通,怎么样方便的把查询条件存在分页栏的queryString 上呢?
新闻标题news_title 的 like 查询 news_title like '%search_info%'
新闻内容 news_info 单选 为空 ,不为空查询 news_info is null , news_info is not null
新闻类别查询 复选 {假设类别为:1 实时新闻,2 历史事件 3专题报道} 当复选 1 3 时 (news_cid = 1 or news_cid = 3)
日期开始时间
日期结束时间设定
--------------------------------------------------------------------------------<form action="#" id="form" name="formName" method="get">
新聞標題:<input type="text" name="new_title" value="<?=$new_title?>" />
內容選擇:<input type="radio" name="new_content" value="1" />不為空 
<input type="radio" name="new_content" value="2" />為空 
新聞類別:<input type="checkbox" name="new_type" value="1">類別1
<input type="checkbox" name="new_type" value="2">類別2
<input type="checkbox" name="new_type" value="3">類別3
时间范围:从<input type="text" name="begin_time" value="<?=$begin_time?>">到<input type="text" name="end_time" value="<?=$end_time?>">
</form>
$new_title=isset($_GET["new_title"])?$_GET["new_title"]:'';
$where =" where 1";
$where.=(!empty($new_title))?" and news_title like '%$new_title%'":""
.....分页部分..你只要将get参数保持在url上.就不会丢失...
找个分页类.
这情部下 生成的where 条件中的是 like 还是 = 还是 in() 是有变化的,这个就因当在表单这块就准备好。
2分页部分,肯定是将get参数保存在url 上,就是这么解决的。针对1, 需要一个专门负责将 post 参数,和get 参数转换成 where 和保存为 queryString 的接口。
为什么写成接口了。 不同的表单构造方式,不同的转换规则时,就用接口来实现了。
针对2 还是那个接口,将传来的参数,暂存,并设置到分页所带的queryString中去。下面我贴点我以前在一个项目中完成的和这相关的代码,我尽量把里面的东西精简,已表达意思,希望对楼主有帮助。。/**
* * 数据列表类.
*
*/
class xList
{
public static $CI = NULL; //CI对象的实例
private $table;
private $where;
private $parameters; //当前分页数,和查询条件,都在parameters 中.
private $rows; //查询结果集
private $pageSize = 10;
private $pageData;
public $IQuery;
function xList()
{
$this->CI = &get_instance(); //取得CI对象的实例
} /**
* *设置表格
*
* @param unknown_type $tableName
*/
function setTable($tableName)
{
$this->table = $tableName;
}
/**
* * 设置查询分页解析接口
*
* @param IsearchQuery $Iseach
*/
function setIQuery(IQuery $IQuery)
{
$this->IQuery = $IQuery;
}
/**
* *
*
*/
function get()
{
//获取查询条件数组,和queryString 参数,并对参数的值进行处理.
list($this->where,$this->parameters) = $this->IQuery->handleparameters();
/**加载模型*/
$model_name = CS_get_model_name($this->table); //取得模型名称
$this->CI->load->model($model_name); //加载模型. $this->getPager();
$this->getRows();
return array($this->pageData,$this->rows);
}
/**
* * 获取分页数据
*
*/
function getPager()
{
$pagesize = $this->parameters["pagesize"];
$offset = ($this->parameters["page"] - 1) * $pagesize;
$model_name = CS_get_model_name($this->table); //取得模型名称
$page_parameters = array(
"recordcount" => $this->CI->$model_name->get_count($this->where), //总页数
"pagesize" => $pagesize //每页显示的记录数
);
$this->CI->load->library("pager", $page_parameters);
/**添加button 按钮*/
if(isset($this->CI->buttons) && sizeof($this->CI->buttons)){
foreach ($this->CI->buttons as $button){
$this->CI->pager->addButton($button);
}
}
$this->CI->pager->setPath("admin/".$this->table."/index");
unset($this->parameters['page']); //删除参数中的分页参数
$this->CI->pager->setParamters($this->parameters); //设置分页链接中需要带的参数
$this->pageData = $this->CI->pager->display(); //取得分页的HTML
}
/**
* * 获取查询数据集
*
*/
function getRows()
{
$pagesize = $this->parameters["pagesize"];
$offset = ($this->parameters["page"] - 1) * $pagesize; $model_name = CS_get_model_name($this->table); //取得模型名称
$this->rows = $this->CI->$model_name->get($this->where,$pagesize,$offset); //稍后加上分页大小
}
/***
更多代码,省略
*/
}
//这样一来,关健的就是IQuery 的实现了,获取查询条件,和得到相应的参数的处理了。
list($this->where,$this->parameters) = $this->IQuery->handleparameters();
$this->CI->pager->setParamters($this->parameters); //这句用来实现将查询条件存至分页栏.<?php
interface IQuery
{
function handleparameters();
function getConfigSearch($configSearch);
}
class adminIQuery implements IQuery
{
public static $CI;
private $regeMap = array(
"QueryEqual"=>"handleEqual"
,"QueryLike"=>"handleLike"
,"QueryNull"=>"handleNull"
,"QueryMult"=>"handleMult"
);
private $where = array();
private $parameters = array();
private $multJoinTag = "__xyx__"; //checkbox 多项搜索时,用于拼接成queryString 的间隔符
private $indexDeep = 4; //deep 深度 例如 http://demo/index.php/admin/menu/index 为4
/**
* * 实现getparameters 接口
*
*/
function handleparameters()
{
/*
///////////////////////////////////////////////////////////////////////////////
解析模式说明.
QueryEqual_Key = $VAL; 例如 QueryEqual_menu_title = 理 则表式对 menu_title 进行 = 查询
QueryLike_Key = $VAL; 例如 QueryLike_menu_title = 理 则表式对 menu_title 进行 like 查询
QueryNull_key = $VAL; 例如 QueryNullmenu_title = 1 ($val 值为1 时) 查询menu_title is null 为0 时查询menu_title is not null
QueryMult_key = $VAL; 例如 QueryNullmenu_cid = array(1,2) 则查询 menu_cid in (1,2)
///////////////////////////////////////////////////////////////////////////////
*/
if(CS_is_post()){
//分页参数的处理,如果同有相关参数,则设为1.
$this->parameters["page"] = 1; //post 搜索时,将page 置为第一页.
if($_POST["pagesize"] && is_numeric($_POST["pagesize"]))
{
$this->parameters["pagesize"] = $_POST["pagesize"];
}
$this->handleArrayParam($_POST);
}else {
$this->CI = &get_instance(); //取得CI对象的实例
$this->parameters = $this->CI->uri->uri_to_assoc($this->indexDeep); //解析URI中的参数
$this->RhandleArrayParam($this->parameters);
}
//返回相应的值.
return array($this->where,$this->parameters);
}
/**
* * 实现通过queryString 和表名,获取搜索值的接口.
*/
function getConfigSearch($configSearch)
{
foreach ($configSearch as $key=>$val):
foreach ($this->parameters as $param_key=>$param_val):
$pattern = "/".$val["search_type"]."/";
if(preg_match($pattern,$param_key))
{
$handleMergeFunction = "merge".$val["search_type"];
$configSearch[$key] = $this->$handleMergeFunction($val,$param_val);
}
endforeach;
endforeach;
return $configSearch;
}
/***
*处理数组的相关参数 搜索相关的参数,写到相应的 $this->paramters 和 $this->where 中去
*/
function handleArrayParam($post)
{
foreach ($post as $key=>$val):
foreach ($this->regeMap as $regeKey =>$regeVal): //匹配规则.
$pattern = "/".$regeKey."/";
if(preg_match($pattern,$key))
{
$this->$regeVal($key,$val);
}else {
continue;
}
endforeach;
endforeach;
}
function RhandleArrayParam($array)
{
foreach ($array as $key=>$val):
foreach ($this->regeMap as $regeKey =>$regeVal): //匹配规则.
$pattern = "/".$regeKey."/";
if(preg_match($pattern,$key))
{
$regeVal = "R".$regeVal;
$this->$regeVal($key,$val);
}else {
continue;
}
endforeach;
endforeach;
}
/**
* *
*
* @param get方式接收的深度 $indexDeep
*/
function setIndexDeep($indexDeep)
{
$this->indexDeep = $indexDeep;
}/**
* **查询参数处理集
*
* @param unknown_type $key
* @param unknown_type $val
*/
////////////////////模糊查询 ////////////////////////////////////////////////////
function handleLike($key,$val){ //post 方式 get 解析
if($this->checkValNotNull(&$val)) {
$key_title = str_replace("QueryLike_","",$key); //找出mul 部分.
$this->parameters += array_map('base_encode', array($key=>"$val"));
$this->where[]= "($key_title like '%$val%')";
}
}
function RhandleLike($key,$val){
if($this->checkValNotNull(&$val)) {
$val = base_decode($val);
$key_title = str_replace("QueryLike_","",$key); //找出mul 部分.
$this->where[]= "($key_title like '%$val%')";
}
}
////////////////////等值搜索 ////////////////////////////////////////////////////
function handleEqual($key,$val)
{
if($this->checkValNotNull(&$val)) {
$key_title = str_replace("QueryEqual_","",$key); //找出mul 部分.
$this->parameters += array_map('base_encode', array($key=>"$val"));
$this->where[]= "($key_title = '$val')";
}
}
function RhandleEqual($key,$val){
if($this->checkValNotNull(&$val)) {
$val = base_decode($val);
$key_title = str_replace("QueryEqual_","",$key); //找出mul 部分.
$this->where[]= "($key_title = '$val')";
}
}
////////////////////复选框搜索 ////////////////////////////////////////////////////
function handleMult($key,$val){
echo "here";
if(is_array($val) && sizeof($val)) //去除零选中状态.
{
$key_title = str_replace("QueryMult_","",$key); //找出mul 部分.
foreach($val as $val_piece)
{
$str_val[]= base_encode($val_piece); //生成parm所用参数数组.
}
$str_mult = implode( $this->multJoinTag, $str_val );
$this->parameters[$key] = $str_mult; //合并生成parameters.
$this->where []= "($key_title in(".implode(",",$val)."))"; //合并生成查询条件.
}
}
function RhandleMult($key,$val){ //通get方式传参进行转换
$val = trim($val);
if($val) {
$key_title = str_replace("QueryMult_","",$key); //找出mul 部分.
$this->parameters[$key] = $val; //合并生成parameters.
$item_array = explode($this->multJoinTag,$val);
$item_array = array_map("base_decode",$item_array);
$this->where []= "($key_title in(".implode(",",$item_array)."))"; //合并生成查询条件.
}
}
////////////////////判断is null ////////////////////////////////////////////////////
function handleNull($key,$val){
$key_title = str_replace("QueryNull_","",$key); //找出mul 部分.
$this->parameters += array_map('base_encode', array($key=>"$val"));
if($val) $this->where[]= "($key_title is NULL)";
else $this->where[]= "($key_title is not NULL)";
}
function RhandleNull($key,$val){
$val = base_decode($val);
$key_title = str_replace("QueryNull_","",$key); //找出mul 部分.
if($val)
{
$this->where[]= "($key_title is NULL)";
}
else
{
$this->where[]= "($key_title is not NULL)";
}
}
function checkValNotNull(&$val){ //空值判断
$val = trim($val);
return $val;
}
}