0

現在、これは私の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::select() はクエリです。私は kohana クエリ ビルダーを使用しています)。

何千人ものユーザーがいる今まで、これはうまくいきました。

これをどのように簡素化して迅速化できますか?

スクリプトが行うことは、$from と $to の間に注文がないすべての人を $orders 配列に保存することです。

4

2 に答える 2

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

結合を使用すると、ユーザーごとに 1 つではなく、1 つのクエリで必要なすべてを取得できるため、はるかに優れています。クエリを編集した人に感謝します:)

于 2012-04-15T19:20:41.200 に答える
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 

/* すべてのユーザーの結合 */

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

/* 'new' & 'delivered' ステータスのものを除く

/*注: ユーザー bob に 2 つの注文があり、1 つが「入荷待ち」の状態で、もう 1 つが「新規」の状態である場合、bob が表示されます...これはあなたが望むものですか? */

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'))
于 2012-04-15T21:02:52.793 に答える