2013-07-28 105 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選擇所有id其中a.department_id=?
  2. $SupportUserTable選擇所有id其中id是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; 

編輯
我發現(不幸的是,怎麼一回事,因爲是很醜陋和雜亂)前面的代碼(我已刪除了所有的控制,如果,但它的工作原理):

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

這是一個嵌套的'if'語句粗糙的集合。考慮使用[例外](http://php.net/manual/en/language.exceptions.php)。 – Herbert

+0

這不是第一次有人說,但我不知道如何,mysqli_stmt_error($ stmt)是一個執行或錯誤? – Razorphyn

+1

嗯。在進一步閱讀之後,顯然mySQLi在異常情況下效果不佳。我想這就是更重要的原因[爲什麼你應該使用PHP的數據庫訪問PDO](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條件的情況。使用底部「醜」代碼,我它冷凝以這樣的:

$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(); 

您可以進一步通過使用UNION具有1像的組合限制所述2次的查詢凝結成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