2012-04-15 34 views
0

目前,這是我的PHP腳本:抓住用戶沒有訂單與MySQL和PHP,簡化這個

  $users = DB::select('id', 'email', 'firstname', 'lastname')->from('users')->execute()->as_array(); 

      $orders = array(); 
      foreach($users as $user) 
      { 
       $anyOrder = DB::select('id')->from('orders') 
       ->where('orders.date_created', 'BETWEEN', array($from, $to)) 
       ->and_where('orders.user_id', '=', $user['id']) 
       ->and_where_open() 
       ->and_where('orders.status', '=', 'new')->or_where('orders.status', '=', 'delivered') 
       ->and_where_close() 
       ->execute()->count(); 

       if($anyOrder == 0) 
       { 
        $orders[] = array('firstname' => $user['firstname'], 'lastname' => $user['lastname'], 'email' => $user['email']); 
       } 
      } 

(DB ::選擇()是一個查詢,使用IM的Kohana查詢生成器)。

這工作正常,直到現在,當我有超過數千用戶。

這怎麼能簡化和更快?

該腳本所做的是將$ from和$之間沒有訂單的所有人保存到$ orders數組中。

回答

1

使用SQL連接查詢並選擇無訂單結果。沿

SELECT id, email, firstname, lastname 
FROM users 
LEFT OUTER JOIN orders ON users.id = orders.user_id 
    AND orders.date_created BETWEEN $start AND $end 
    AND orders.status = 'new' OR orders.status = 'delivered' 
WHERE orders.id IS NULL 

使用連接線要好得多,因爲你會得到你在一個查詢所需要的一切,而不是每個用戶一個。 感謝誰所有用戶*/

(SELECT id, email, firstname, lastname 
FROM users 
INNER JOIN orders 
    ON users.id = orders.user_id 
    AND orders.date_created BETWEEN $start AND $end 

/*除了編輯查詢:)

+0

如果我使用一個連接: SELECT ID,電子郵件,名字,姓氏來自用戶的 INNER JOIN命令ON(orders.user_id = users.id) WHERE(...) 然後我將獲得所有有訂單的用戶。我希望抓住以下用戶:1.訂單中沒有任何行2.訂單中有行,但它們不是狀態「已交付」或「新」 – Karem 2012-04-15 19:31:42

+0

INNER JOIN需要用戶訂購。左連接表示即使沒有訂單,也要返回所有用戶。 [考慮](http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html) – xQbert 2012-04-15 19:32:57

+0

不知道我是否理解:然後選擇所有用戶並減去找到的用戶這裏。 – Matsemann 2012-04-15 19:34:26

0

/獲取所有用戶沒有任何訂單/

SELECT id, email, firstname, lastname 
FROM users 
LEFT JOIN orders 
    ON users.id = orders.user_id 
    AND orders.date_created BETWEEN $start AND $end 
WHERE orders.id IS NULL 
UNION 

/*聯盟的人那些'新'&'交付'狀態

/*注意:如果用戶bob有2個訂單,一個是在'缺貨'的狀態,一個是'新' 然後鮑勃將出現......這是你想要的? */

MINUS 
SELECT id, email, firstname, lastname 
FROM users 
INNER JOIN orders 
    ON users.id = orders.user_id 
    AND orders.date_created BETWEEN $start AND $end 
WHERE Orders.status in ('new','delivered'))