mysql Query的IN语句变得不可预测

时间:2016-01-05 09:52:42

标签: php mysql

我将所有注册用户的可用性按以下逗号分隔的字符串中的三列存储:

user 1:
teaching: english

morning = '';
afternoon = 'Thrs,Fri,Sat,Sun'; 
evening = 'Thrs,Fri,Sat,Sun';

User 2
teaching: english

morning = 'Sat';
afternoon = 'Sat,Sun,Fri';  
evening = 'Sat,Sun,Fri';    

说我搜索星期六下午和晚上可用的导师。我认为查询将返回它们两个,因为用户的下午和晚上列都有'星期六'。但它返回空数组。

这是我的浏览器解释查询。我在phpmyadmin中运行了这个,但没有返回任何结果。

SELECT * , (3956 * 2 * ASIN(SQRT( POWER(SIN(('2.993518' - lat) * pi()/180 / 2), 2) +COS('2.993518' * pi()/180) * COS(lat * pi()/180) * POWER(SIN(('101.7874058' - lon) * pi()/180 / 2), 2) ))) as distance from posts WHERE posts.subname LIKE '%english%' AND posts.pricing <= '115' AND(posts.afternoon IN('Sat')或posts.evening IN('Sat')) GROUP BY posts.UUID having distance <= '40' order by distance

在这里,我试图在下午和晚上'星期四'寻找用户。我想它应该返回user1,因为只有user1在星期四可用,但它不会返回任何结果:

SELECT * , (3956 * 2 * ASIN(SQRT( POWER(SIN(('2.993518' - lat) * pi()/180 / 2), 2) +COS('2.993518' * pi()/180) * COS(lat * pi()/180) * POWER(SIN(('101.7874058' - lon) * pi()/180 / 2), 2) ))) as distance from posts WHERE posts.subname LIKE '%flute%' AND posts.pricing <= '115' AND(posts.afternoon IN('Thrs')或posts.evening IN('Thrs')) GROUP BY posts.UUID having distance <= '40' order by distance

那么在地球上它会返回结果吗?

当我在星期六早上,下午和晚上搜索。我只是不明白这个查询是如何进行搜索的。为什么我没有得到预期的结果,哪里是我的错?如果有人帮助我,这会很有帮助,因为我浪费了很多天这个!

以上的完整PHP代码:

<?php
JSON formatted data received via ajax
$return = '{"avail":["Wed-2,Thrs-2","Thrs-3"]}';

In the above -1 means for monrning, -2 for afternoon and -3 for evening.I'm categorising them below.'
$avail = $data['avail'];
$days = array();
$cols = array();

$size = sizeof($avail);
if(($avail != "")&&($size > 1)){
$periods = array();
foreach($avail as $v){
    list($day, $column) = explode("-", $v); // make sure you validated the data to avoid errors
   $periods[$column][] = "'" . mysql_escape_string($day) . "'"; //strtolower// PHP would automatically create an empty array if $periods[$column] was not defined
}
$intToCol = array(1 => "morning", 2 => "afternoon", 3 => "evening");
// $periods should now be identical to ["2" => ["'sun'", "'mon'"], "3" => ["'sun'"]]

$conditions = array();
foreach($periods as $int => $days){
    $dayString = implode(",", $days);
    $conditions[] = " FIND_IN_SET ($dayString,  posts." . $intToCol[$int].")" ;
}
$add_here = "AND (" . implode(" OR ", $conditions) . ")";
}else if(($avail != "")&&($size == 1))
{
    foreach($avail as $k=>$v)
        {
             $v;

            $array = explode('-', $v);
            $day =$array[0]; // Wed
            $column =  $array[1]; // 2

            if($column == 1)
            {
            $col = "morning";

            }
            if($column == 2)
            {
                $col = "afternoon";
            }
            if($column == 3)
            {
                $col = "evening";
            }

        }

    $add_here = " posts.".$col." = '".$day."' ";

    $sql = "SELECT * , (3956 * 2 * ASIN(SQRT( POWER(SIN(('$lat' - lat) *  pi()/180 / 2), 2) +COS('$lat' * pi()/180) * COS(lat * pi()/180) * POWER(SIN(('$lon' - lon) * pi()/180 / 2), 2) ))) as distance  from posts WHERE posts.subname LIKE '%$subject%' AND posts.pricing <= '$rate' ".$add_here."".$IsTutionCentre." GROUP BY posts.UUID having  distance <= '$distance' order by distance";

    $stmt =connection::$pdo->prepare($sql);
        $stmt->execute();
        $place=array();
        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { 
               $place[] = $row;
               }
               $_SESSION['subject'] = $place;

    //send back to ajax call  made page
    echo json_encode($place);
}
?>

1 个答案:

答案 0 :(得分:1)

  

afternoon = 'Thrs,Fri,Sat,Sun';
  evening = 'Thrs,Fri,Sat,Sun';

当一组值作为csv存储在单行字段中时,使用'IN'不起作用。您必须使用&#39; FIND_IN_SET &#39;

更改

AND (posts.afternoon IN ('Sat') OR posts.evening IN ('Sat'))

AND (    FIND_IN_SET( 'Sat', posts.afternoon )
      OR FIND_IN_SET( 'Sat', posts.evening ) )

您可以将其应用于其他日期。

文档参考
FIND_IN_SET(str,strlist)

  • 如果字符串str在,则返回1到N范围内的值 字符串列表strlist由N个子串组成。字符串列表是 由“,”字符分隔的子串组成的字符串。如果 第一个参数是一个常量字符串,第二个参数是一列 类型SET,FIND_IN_SET()函数优化使用位 算术。如果str不在strlist中,或者strlist是,则返回0 空字符串。如果任一参数为NULL,则返回NULL。这个功能 如果第一个参数包含逗号(“,”),则无法正常工作 字符。