Php foreach($idx=>$url的url){ $params['url'.$idx]=$url; } $static_其中[]='url IN(:'。内爆(',:',数组_键($params))'; } //筛选查询中使用的现有参数 //空()对于一般用途来说不是个好主意, //因为某些有效值可能被识别为空(int 0,字符串“0”) $params+=数组过滤器( 压缩(数组_键($optional_where),数组_键($optional_have)), 函数($value){返回!空($value);} ); //连接条件字符串 //具有未过滤掉的相应参数 //或者这些没有参数(静态) $where_子句=内爆('AND',$static_where+array_intersect_key($optional_where,$params)); $having_子句=内爆('AND',$static_having+array_intersect_key($optional_having,$params)); //不需要没有条件的子句-就像(!empty($where)){…} 空($where\u子句)或$where\u子句='where'$where_条款; 空($having_子句)或$having_子句='having'$有_条款; $sql=“选择 hash, 总计(行为时间消耗)为时间消耗, 新表格。百分位数排名, 将(*)计为总数 从行为上看,, 在behavior.hash=accountries.hash上内部加入观众, Behavior.hash上的内部联接新表=新表.hash {$where_子句} 按行为分组。哈希 {$having_子句}”; //PDO部件 $query=$pdo->prepare($sql); $result=$query->execute($params); //...

Php foreach($idx=>$url的url){ $params['url'.$idx]=$url; } $static_其中[]='url IN(:'。内爆(',:',数组_键($params))'; } //筛选查询中使用的现有参数 //空()对于一般用途来说不是个好主意, //因为某些有效值可能被识别为空(int 0,字符串“0”) $params+=数组过滤器( 压缩(数组_键($optional_where),数组_键($optional_have)), 函数($value){返回!空($value);} ); //连接条件字符串 //具有未过滤掉的相应参数 //或者这些没有参数(静态) $where_子句=内爆('AND',$static_where+array_intersect_key($optional_where,$params)); $having_子句=内爆('AND',$static_having+array_intersect_key($optional_having,$params)); //不需要没有条件的子句-就像(!empty($where)){…} 空($where\u子句)或$where\u子句='where'$where_条款; 空($having_子句)或$having_子句='having'$有_条款; $sql=“选择 hash, 总计(行为时间消耗)为时间消耗, 新表格。百分位数排名, 将(*)计为总数 从行为上看,, 在behavior.hash=accountries.hash上内部加入观众, Behavior.hash上的内部联接新表=新表.hash {$where_子句} 按行为分组。哈希 {$having_子句}”; //PDO部件 $query=$pdo->prepare($sql); $result=$query->execute($params); //...,php,mysql,Php,Mysql,您只能将内爆函数更改为此代码 $conditionString = implode(' ', array_map(function($item) { if ((strpos($item, 'timeSpent') !== false)) return 'HAVING '.$item; return 'AND '.$item; }, $conditions)); 请注意您的代码易受攻击。 有关更多信息,请参见:这里是一种使用字符串串联而不是内爆的不太复杂的方法。“技巧”是以1=1开始条件

您只能将内爆函数更改为此代码

$conditionString = implode(' ', array_map(function($item) {
if ((strpos($item, 'timeSpent') !== false))
    return 'HAVING '.$item;
return 'AND '.$item;
}, $conditions));
请注意您的代码易受攻击。


有关更多信息,请参见:

这里是一种使用字符串串联而不是
内爆的不太复杂的方法。“技巧”是以
1=1
开始条件。因此,以下每个条件都可以从
开始

$andWhere='';
$andHaving='';
$params=[];
如果(!空($上次访问)){
$andWhere.=“AND behavior.TIMESTAMP>=CURDATE()-间隔:最后一次就诊日期和行为.TIMESTAMP=:大于”;
$params['more_than']=$more_than;
}
如果(!empty($time_-spend)){
$andHaving.=“和时间花费>=:花费的时间”;
$params['time\u-speed']=$time\u-speed;
}
如果(!空($lead_评分)){
$andHaving.=“和新的表格百分比排名>=:领先得分”;
$params['lead_scoring']=$lead_scoring;
}
$URLP占位符=[];
foreach($val作为$key=>$val){
$URLPocholders[]=“:url_$key”;
$params[“url_$key”]=$val;
}
如果(计数($VAL)>0){
$inUrl=内爆(“,”,$URLP占位符);
$andWhere.=“和中的url($inUrl)”;
}
$sql=”
选择behavior.hash,
总计(行为时间消耗)为时间消耗,
新表格。百分位数排名,
将(*)计为总数
从行为
在behavior.hash=acquisition.hash上加入观众
在behavior.hash上联接新的\u表=新的\u表.hash
其中1=1{$andWhere}
按行为分组。哈希
有1=1{$andHaving}
";
#var_导出($sql);
#var_出口(参数);
$sth=$dbh->prepare($sql);
$sth->execute($params);
$data=$sth->fetchAll(PDO::FETCH_ASSOC);
#var_导出(数据);
有像这样的样本数据

$last_visit='';
$from_country='UK';
$more_than='5';
$花费的时间='3';
$lead_得分=“”;
$VAL=['u1','u2'];
您将得到以下查询:

SELECT behavior.hash,
总计(行为时间消耗)为时间消耗,
新表格。百分位数排名,
将(*)计为总数
从行为
在behavior.hash=acquisition.hash上加入观众
在behavior.hash上联接新的\u表=新的\u表.hash
其中1=1和acquisite.country=:from_country和url IN(:url_0,:url_1)
按行为分组。哈希
有1=1和COUNT(*)>=:大于和时间花费>=:花费的时间
使用这些绑定:

数组(
“from_country”=>“UK”,
'超过'=>'5',
“花费的时间”=>“3”,
'url_0'=>'u1',
'url_1'=>'u2',
)
$url='url=“”。内爆(“”或url=“”,$vals)。”;
$conditions=array();
$havings=array();
如果(!empty($last_visit))$conditions[]=“behavior.TIMESTAMP>=DATE_SUB(CURDATE(),INTERVAL.”.$last_visit.“DAY”)和behavior.TIMESTAMP=”“$more_-than。””;
如果(!empty($time_-speed))$havings[]=“timeSpent>=”“$time_-speed。””;
如果(!empty($lead_scoring))$havings[]=“new_table.percentile_rank>=””“$lead_scoring.””;
$conditionString=内爆('AND',$conditions);
$havingString='';
如果(计数($havings)>0){
$havinString='having'。内爆(',',$havings);
}
$sql=“SELECT behavior.hash,
总计(行为时间消耗)为时间消耗,
新表格。百分位数排名,
将(*)计为总数
从行为上看,,
观众
新表
其中($url)和“..$conditionString.$HavinString;

我更新了我的问题,添加了更多的输出代码。您使用$conditionString=introde('AND',$conditions)完成了这些操作,这就是为什么会出现这个问题and@krishnpatel是的,我明白这一点。你应该实现不同的逻辑,这样做很容易。将您的
$conditions
分为
$where\u conditions
$having\u conditions
。但这不是唯一的问题——另一个是SQL注入。您可以考虑使用一些查询生成器库,该库将为您处理或构建自己的查询生成器库(但它比此连接更困难)。
$url= 'url="'.implode('" OR url="', $vals).'"';

$conditions = array();

if (!empty($last_visit)) $conditions[] = "behaviour.TIMESTAMP >= DATE_SUB( CURDATE( ) , INTERVAL '".$last_visit."' DAY) AND behaviour.TIMESTAMP < DATE_ADD( CURDATE( ) , INTERVAL 1 DAY ) ";
if (!empty($from_country)) $conditions[] = "audience.country = '".$from_country."'";
if (!empty($more_than)) $conditions[] = "COUNT( * ) >= '".$more_than."'"; 
if (!empty($time_spent)) $conditions[] = "timeSpent >= '".$time_spent."'";
if (!empty($lead_scoring)) $conditions[] = "new_table.percentile_rank >= '".$lead_scoring."'";


$conditionString = implode(' AND ', $conditions);


$sql = "SELECT behaviour.hash, 
       Sum(behaviour.timespent) AS timeSpent, 
       new_table.percentile_rank, 
       Count( * ) AS total 
FROM   behaviour, 
       audience, 
       new_table 
WHERE  ($url) AND ".$conditionString;
SELECT behaviour.hash, 
       SUM(behaviour.timespent) AS timeSpent, 
       new_table.percentile_rank, 
       Count(*) AS total 
FROM   behaviour, 
       audience, 
       new_table 
WHERE  ( url = "/10369" ) 
       AND behaviour.timestamp >= Date_sub(Curdate(), interval '3' day) 
       AND behaviour.timestamp < Date_add(Curdate(), interval 1 day) 
       [missing]     AND behaviour.hash = audience.hash
       [missing]     AND behaviour.hash = new_table.hash
       AND audience.country = 'it' 
       [missing]     GROUP BY behaviour.hash
       [wrong]       AND timespent >= '20' ////// it should be HAVING /////
       AND new_table.percentile_rank >= '30'
$conditions = array();

if (!empty($last_visit)) $conditions[] = "behaviour.TIMESTAMP >= DATE_SUB( CURDATE( ) , INTERVAL '".$last_visit."' DAY) AND behaviour.TIMESTAMP < DATE_ADD( CURDATE( ) , INTERVAL 1 DAY ) ";
if (!empty($from_country)) $conditions[] = "audience.country = '".$from_country."'";


$conditionString = implode(' AND ', $conditions);

$conditions_having = array();
if (!empty($more_than)) $conditions_having[] = "COUNT( * ) >= '".$more_than."'"; 
if (!empty($time_spent)) $conditions_having[] = "timeSpent >= '".$time_spent."'";
if (!empty($lead_scoring)) $conditions_having[] = "new_table.percentile_rank >= '".$lead_scoring."'";

$conditionString .= " GROUP  BY behaviour.hash" 
if(count($conditions_having))
$conditionString .= " HAVING ".implode(' AND ', $conditions_having); 

$sql = "SELECT behaviour.hash, 
       Sum(behaviour.timespent) AS timeSpent, 
       new_table.percentile_rank, 
       Count( * ) AS total 
FROM   behaviour, 
       audience, 
       new_table 
WHERE  ($url) AND ".$conditionString;
    $pdo = new PDO(/* See http://php.net/manual/en/pdo.construct.php */);

    $whereConditions = [];
    $havingConditions = [];
    $parameters = [];

    if (!empty($last_visit)) {
        $whereConditions[] = "behaviour.TIMESTAMP >= DATE_SUB( CURDATE( ) , INTERVAL :last_visit DAY) AND behaviour.TIMESTAMP < DATE_ADD( CURDATE( ) , INTERVAL 1 DAY ) ";
        $parameters['last_visit'] = $last_visit;
    }
    if (!empty($from_country)) {
        $whereConditions[] = "audience.country = :from_country";
        $parameters['from_country'] = $from_country;
    }
    if (!empty($more_than)) {
        $havingConditions[] = "COUNT( * ) >= :more_than";
        $parameters['more_than'] = $more_than;
    }
    if (!empty($time_spent)) {
        $havingConditions[] = "timeSpent >= :time_spent";
        $parameters['time_spent'] = $time_spent;

    }
    if (!empty($lead_scoring)) {
        $havingConditions[] = "new_table.percentile_rank >= :lead_scoring";
        $parameters['lead_scoring'] = $lead_scoring;
    }

    if (count($vals)) {
        $escapedUrlList = implode(', ', array_map(function ($url) use ($pdo) {
            return $pdo->quote($url);
        }, $vals));
        $whereConditions[] = "url IN($escapedUrlList)";
    }

    $whereClause = count($whereConditions) ? ' AND ' . implode(' AND ', $whereConditions) : '';
    $havingClause = count($havingConditions) ? ' HAVING ' . implode(' AND ', $havingConditions) : '';

    $statement = $pdo->prepare("
        SELECT behaviour.hash, 
            Sum(behaviour.timespent) AS timeSpent, 
            new_table.percentile_rank, 
            Count(*) AS total 
        FROM behaviour, 
            audience, 
            new_table 
        WHERE behaviour.hash = audience.hash 
            AND behaviour.hash = new_table.hash 
            {$whereClause}
        GROUP  BY behaviour.hash
        {$havingClause}
    ");

    $result = $statement->execute($parameters);
//assume established PDO connection - example:
try {
    $pdo = new PDO("mysql:dbname={$database_name};host=localhost", $user, $password);
} catch (PDOException $e) {
    echo 'Connection failed: ' . $e->getMessage();
}

//static: conditional strings without parameters check (no keys required)
//conditional: assoc - keys should match both query placeholders and variable names
$static_where = [];
$optional_where = [
    'last_visit'   => 'behaviour.TIMESTAMP >= DATE_SUB(CURDATE(), INTERVAL :last_visit DAY) AND behaviour.TIMESTAMP < DATE_ADD(CURDATE(), INTERVAL 1 DAY)',
    'from_country' => 'audience.country = :from_country'
];

$static_having = [];
$optional_having = [
    'more_than'    => 'COUNT(*) >= :more_than',
    'time_spent'   => 'timeSpent >= :time_spent',
    'lead_scoring' => 'new_table.percentile_rank >= :lead_scoring'
];

//params: query parameters array - assigned manually + resolved from optional variables
$params = [];

//resolve condition from $urls array
if (count($urls) == 1) {
    $static_where[] = 'url = :url';
    $params['url'] = reset($urls);
} else if (!empty($urls)) {
    foreach ($urls as $idx => $url) {
        $params['url' . $idx] = $url;
    }
    $static_where[] = 'url IN(:' . implode(', :', array_keys($params)) . ')';
}

//filtering existing params used in query
//empty() is not a good idea for general purpose though,
//because some valid values might be recognised as empty (int 0, string '0')
$params += array_filter(
    compact(array_keys($optional_where), array_keys($optional_having)),
    function ($value) { return !empty($value); }
);

//concatenating conditional strings
//with corresponding params that weren't filtered out
//or these without params (static)
$where_clause = implode(' AND ', $static_where + array_intersect_key($optional_where, $params));
$having_clause = implode(' AND ', $static_having + array_intersect_key($optional_having, $params));

//don't need clauses without conditions - same as if (!empty($where)) {...}
empty($where_clause) or $where_clause = 'WHERE ' . $where_clause;
empty($having_clause) or $having_clause = 'HAVING ' . $having_clause;

$sql = "SELECT 
          behaviour.hash,
          Sum(behaviour.timespent) AS timeSpent,
          new_table.percentile_rank,
          Count( * ) AS total 
        FROM behaviour,
        INNER JOIN audience ON behaviour.hash = audience.hash,
        INNER JOIN new_table ON behaviour.hash = new_table.hash 
        {$where_clause}
        GROUP BY behaviour.hash 
        {$having_clause}";

//PDO part
$query = $pdo->prepare($sql);
$result = $query->execute($params);
//...
$conditionString = implode(' ', array_map(function($item) {
if ((strpos($item, 'timeSpent') !== false))
    return 'HAVING '.$item;
return 'AND '.$item;
}, $conditions));
  $url= 'url="'.implode('" OR url="', $vals).'"';

  $conditions = array();
  $havings = array();

    if (!empty($last_visit)) $conditions[] = "behaviour.TIMESTAMP >= DATE_SUB( CURDATE( ) , INTERVAL '".$last_visit."' DAY) AND behaviour.TIMESTAMP < DATE_ADD( CURDATE( ) , INTERVAL 1 DAY ) ";
    if (!empty($from_country)) $conditions[] = "audience.country = '".$from_country."'";
    if (!empty($more_than)) $havings[] = "COUNT( * ) >= '".$more_than."'"; 
    if (!empty($time_spent)) $havings[] = "timeSpent >= '".$time_spent."'";
    if (!empty($lead_scoring)) $havings[] = "new_table.percentile_rank >= '".$lead_scoring."'";


    $conditionString = implode(' AND ', $conditions);

    $havingString = '';
    if(count($havings)>0) {
         $havingString = ' having '.implode(', ', $havings);    
    }

    $sql = "SELECT behaviour.hash, 
           Sum(behaviour.timespent) AS timeSpent, 
           new_table.percentile_rank, 
           Count( * ) AS total 
    FROM   behaviour, 
           audience, 
           new_table 
    WHERE  ($url) AND ".$conditionString.$havingString;