2013-07-28 3 views
3

Я пытался уменьшить количество операций функции только один запрос, но теперь я не могу получить никакого результата: Получение результатов из базы данных с JOIN

function retrive_avaible_operator($Hostname, $Username, $Password, $DatabaseName, $SupportUserPerDepaTable, $SupportUserTable,$dep){ 
    $query = "SELECT b.id 
       FROM ".$SupportUserTable." b 
       INNER JOIN ".$SupportUserPerDepaTable." a 
        ON b.id=a.user_id 
       WHERE a.department_id=? AND b.holiday='0' AND a.user_id!=".$_SESSION['id']." 
       ORDER BY b.assigned_tickets ASC LIMIT 1"; 

    $mysqli = new mysqli($Hostname, $Username, $Password, $DatabaseName); 
    $stmt = $mysqli->stmt_init(); 
    $prepared = $stmt->prepare($query); 

    if($prepared){ 
     if($stmt->bind_param('i', $dep)){ 
      if($stmt->execute()){ 
       $stmt->store_result(); 
       $result = $stmt->bind_result($camaro); 
       if($stmt->num_rows>0){ 
        while (mysqli_stmt_fetch($stmt)) 
         $selopid=$camaro; 
        return $selopid; 
       } 
       else 
        return 'No Operator Available'; 
      } 
      else 
       return mysqli_stmt_error($stmt); 
     } 
     else 
      return mysqli_stmt_error($stmt); 
    } 
    else 
     return mysqli_stmt_error($stmt); 
} 

До этого попробовать эти операции (это 2 разных запросы):

  1. выбрать все идентификаторы из $SupportUserPerDepaTable где a.department_id=?
  2. выбрать все идентификаторы из $SupportUserTable, где идентификатора внутри Previo нам результаты и holiday='0'

Она работала, но теперь он возвращает только No Operator Available

Также эти таблицы:

CREATE TABLE IF NOT EXISTS `razorphyn_support_user_departments` (
`id`    BIGINT(11) UNSIGNED NOT NULL AUTO_INCREMENT, 
`department_id`  BIGINT(11) UNSIGNED NOT NULL, 
`department_name` VARCHAR(70)    NOT NULL, 
`user_id`   BIGINT(11) UNSIGNED NOT NULL, 
`holiday`   ENUM('0','1')   NOT NULL DEFAULT '0', 
PRIMARY KEY (`id`), 
UNIQUE KEY(`department_name`,`user_id`), 
INDEX(`department_id`,`department_name`,`user_id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=0; 

и

CREATE TABLE IF NOT EXISTS `razorphyn_support_users` (
`id`    BIGINT(15)  UNSIGNED  NOT NULL AUTO_INCREMENT, 
`name`    VARCHAR(50)      NOT NULL, 
`mail`    VARCHAR(50)      NOT NULL, 
`password`   VARCHAR(200)     NOT NULL, 
`reg_key`   VARCHAR(260)     , 
`tmp_password`  VARCHAR(87)      , 
`ip_address`  VARCHAR(50)      NOT NULL, 
`status`   ENUM('0','1','2','3','4')  NOT NULL DEFAULT '3', 
`holiday`   ENUM('0','1')     NOT NULL DEFAULT '0', 
`mail_alert`  ENUM('no','yes')    NOT NULL DEFAULT 'yes', 
`assigned_tickets` INT(5)   UNSIGNED  NOT NULL DEFAULT 0, 
`solved_tickets` BIGINT(11)  UNSIGNED  NOT NULL DEFAULT 0, 
`number_rating`  BIGINT(6)  UNSIGNED  NOT NULL DEFAULT 0, 
`rating`   DECIMAL(4,2) UNSIGNED  NOT NULL DEFAULT 0, 
PRIMARY KEY (`id`), 
UNIQUE KEY(`mail`), 
INDEX (`name`,`mail`,`status`,`holiday`,`assigned_tickets`,`solved_tickets`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=55; 

EDIT
Я нашел (к сожалению, beacuse очень некрасиво и неаккуратно) предыдущий код (я удалил все управление, если, но он работает):

function retrive_avaible_operator($Hostname, $Username, $Password, $DatabaseName, $SupportUserPerDepaTable, $SupportUserTable,$dep){ 

$query = "SELECT `user_id` FROM ".$SupportUserPerDepaTable." WHERE `department_id`=? AND `user_id`!=".$_SESSION['id'] ; 
$mysqli = new mysqli($Hostname, $Username, $Password, $DatabaseName); 
$stmt = $mysqli->stmt_init(); 
$prepared = $stmt->prepare($query); 
    $stmt->bind_param('i', $dep) 
     $stmt->execute() 
      $stmt->store_result(); 
      $operator=array(); 
      $result = $stmt->bind_result($camaro); 
      if($stmt->num_rows>0){ 
       while (mysqli_stmt_fetch($stmt)) 
        $operator[]=$camaro; 
       $operator=join(',',$operator); 
       $query = "SELECT `id` FROM ".$SupportUserTable." WHERE `id` IN (".$operator.") AND `holiday`='0' ORDER BY `assigned_tickets` ASC LIMIT 1" ; 
       $prepared = $stmt->prepare($query); 
       $prepared) 
        $stmt->execute() 
         $stmt->store_result(); 
         $result = $stmt->bind_result($camaro); 
         if($stmt->num_rows>0){ 
          while (mysqli_stmt_fetch($stmt)) 
           $selopid=$camaro; 
          return $selopid; 
         } 
         else{ 
          $query = "SELECT `id` FROM ".$SupportUserTable." WHERE `status`=2 AND `holiday`=0 AND `id`!=".$_SESSION['id']." ORDER BY `assigned_tickets` ASC, `solved_tickets` ASC LIMIT 1" ; 
          $prepared = $stmt->prepare($query); 
          $prepared 
           $stmt->execute() 
            $stmt->store_result(); 
            $result = $stmt->bind_result($camaro); 
            if($stmt->num_rows>0){ 
             while (mysqli_stmt_fetch($stmt)) 
              $selopid=$camaro; 
             return $selopid; 
            } 
            else 
             return 'No Operator Available'; 
         } 
      } 
      else{ 
       $query = "SELECT `id` FROM ".$SupportUserTable." WHERE `status`='2' AND `holiday`='0' AND `id`!=".$_SESSION['id']." ORDER BY `assigned_tickets` ASC, `solved_tickets` ASC LIMIT 1" ; 
       $prepared = $stmt->prepare($query); 
        $stmt->execute() 
         $stmt->store_result(); 
         $result = $stmt->bind_result($camaro); 
         if($stmt->num_rows>0){ 
          while (mysqli_stmt_fetch($stmt)) 
           $selopid=$camaro; 
          return $selopid; 
         } 
         else 
          return 'No Operator Available'; 
      } 
$mysqli->close(); 
} 
+0

Это один gnarly набор вложенных операторов 'if'. Подумайте об использовании [исключений] (http://php.net/manual/en/language.exceptions.php). – Herbert

+0

Это не первый раз, когда кто-то говорит это, но я не понимаю, как, mysqli_stmt_error ($ stmt) является исполнением или ошибкой? – Razorphyn

+1

Хм. После некоторого дальнейшего чтения, очевидно, mySQLi не работает так хорошо с исключениями. Я думаю, что это тем более [Почему вы должны использовать PDO PHP для доступа к базе данных) (http://net.tutsplus.com/tutorials/php/why-you-should-be-using-phps-pdo-for- доступа к базам данных /). Это, конечно, мое мнение. try/catch намного проще, чем пытаться проверить все возможные ошибки. Он также предотвращает обработку ошибок из логического потока программы. – Herbert

ответ

0

Вы должны быть в состоянии конденсироваться это значительно. Сначала вы запрашиваете $SupportUserPerDepaTable, чтобы получить user_id, только чтобы присоединиться к ним в разделенную запятыми строку для вашего второго запроса. Вы должны устранить это, превратив его в подзапрос. 3-й и 4-й запросы являются избыточными, это продукт предыдущего случая if/else, поэтому вы можете объединить их сейчас, когда мы исключили условие top if. Использование нижнего «уродливый» код, я конденсируюсь его к этому:

$mysqli = new mysqli($Hostname, $Username, $Password, $DatabaseName); 
$stmt = $mysqli->stmt_init(); 
$query = " 
SELECT  `id` 
FROM  ".$SupportUserTable." 
WHERE  `id` IN (
    SELECT  `user_id` 
    FROM  ".$SupportUserPerDepaTable." 
    WHERE  `department_id`= ? 
    AND   `user_id`!=".$_SESSION['id']." 
) 
AND   `holiday`='0' 
ORDER BY `assigned_tickets` ASC 
LIMIT  1" ; 

$prepared = $stmt->prepare($query); 
$stmt->bind_param('i', $dep); 
$stmt->execute(); 
$stmt->store_result(); 
$operator=array(); 
$result = $stmt->bind_result($camaro); 
if($stmt->num_rows>0){ 
    while (mysqli_stmt_fetch($stmt)) 
     $selopid=$camaro; 
    return $selopid; 
} 
else{ 
    $query = " 
    SELECT  `id` 
    FROM  ".$SupportUserTable." 
    WHERE  `status`= 2 
    AND   `holiday`=0 
    AND   `id`!=".$_SESSION['id']." 
    ORDER BY `assigned_tickets` ASC 
       ,`solved_tickets` ASC 
    LIMIT  1" ; 
    $prepared = $stmt->prepare($query); 
    $stmt->execute(); 
    $stmt->store_result(); 
    $result = $stmt->bind_result($camaro); 
    if($stmt->num_rows>0){ 
     while (mysqli_stmt_fetch($stmt)) 
      $selopid=$camaro; 
     return $selopid; 
    } 
    else{ 
     return 'No Operator Available'; 
    } 
} 
$mysqli->close(); 

Вы можете дополнительно конденсировать 2 запросов в 1 с помощью UNION с комбинированным лимитом 1 как:

(
    SELECT  `id` 
    FROM  ".$SupportUserTable." 
    WHERE  `id` IN (
     SELECT  `user_id` 
     FROM  ".$SupportUserPerDepaTable." 
     WHERE  `department_id`= ? 
     AND   `user_id`!=".$_SESSION['id']." 
    ) 
    AND   `holiday`='0' 
    ORDER BY `assigned_tickets` ASC 
    UNION 
    SELECT  `id` 
     FROM  ".$SupportUserTable." 
     WHERE  `status`= 2 
     AND   `holiday`=0 
     AND   `id`!=".$_SESSION['id']." 
     ORDER BY `assigned_tickets` ASC 
        ,`solved_tickets` ASC 
) 
LIMIT  1; 

или, возможно, с помощью OR условия в зависимости от кода статуса работника в таблице DEPT, как:

SELECT  `id` 
FROM  ".$SupportUserTable." 
WHERE  `holiday`='0' 
AND (  
     `id` IN (
      SELECT  `user_id` 
      FROM  ".$SupportUserPerDepaTable." 
      WHERE  `department_id`= ? 
      AND   `user_id`!=".$_SESSION['id']." 
     ) 
     AND  `status`= ('some code other than 2?') 
    ) 
    OR (
       `status`= 2 
     AND  `id`! = ".$_SESSION['id']." 
) 
ORDER BY status (asc or desc?) 
      ,`assigned_tickets` ASC 
      ,`solved_tickets` ASC 
LIMIT  1; 

Я нету испытал это как бы слишком много времени, чтобы установить таблицы базы данных, вводить образцы данных и проверять все это, поэтому простите меня, если есть небольшие ошибки, но это должно указывать на вас в правильном направлении. Если это не работает, и вы хотите отправить некоторые данные образца в http://sqlfiddle.com/ и дать пару примеров ожидаемого вывода, я попробую несколько запросов, чтобы увидеть, что я могу сделать.

+0

Я не знаю почему, но он начал работать с вопросом вопроса, однако неплохо использовать SELECT внутри запроса SELECT? – Razorphyn

+0

Будьте осторожны с запросами, которые «внезапно работают», когда они не были раньше, поскольку они могут работать только при определенных условиях, когда вы случайно выбираете то, что хотите ... Если ваша таблица подселектов имела миллионы строк, это, безусловно, замедляло бы запрос, но если его разумный размер (десятки, сотни), и особенно если ваши таблицы правильно проиндексированы, он все равно будет довольно быстрым. В любом случае это будет более эффективным, чем выполнение запроса для циклического преобразования значений, добавляемых к текстовой строке, только для использования этой текстовой строки во втором запросе. – WebChemist

Смежные вопросы