1

クエリの sql ヘルプが必要です。お店の顧客を一覧表示するビューを作成したいと考えています。これは、1 つ以上の予約 (テーブル予約) または 1 つ以上の注文 (テーブル shop_orders) を行ったユーザー テーブルの選択です。

-------------    --------------
| users:    |    | shops:     |
-------------    --------------
| id (PK)   |    | id (PK)    |
-------------    --------------

------------------    ----------------
| reservations:  |    | shops_orders:|
------------------    ----------------
| id (PK)        |    | id (PK)      |
| user_id (FK)   |    | user_id (FK) |
| shop_id (FK)   |    | shop_id (FK) |
------------------    ----------------

これは私の出発点です。

SELECT u.*,
       r.shop_id,
      (SELECT count(*)
       FROM reservations r
       WHERE r.user_id = u.id) AS num_reservations,
      (SELECT count(*)
       FROM shop_orders so
       WHERE so.user_id = u.id) AS num_orders
FROM users u
INNER JOIN (SELECT r.user_id,
                   r.shop_id
            FROM reservations r
            UNION 
            SELECT so.user_id,
                   so.shop_id
            FROM shop_orders so) AS r ON u.id = r.user_id
GROUP BY u.id

このビューへのすべてのクエリは、shop_id によってフィルター処理され、具体的なショップ (ショップの管理エリア) の顧客のみが表示されます。

予約または注文がある顧客のみを選択します (num_reservations > 0 OR num_orders > 0)

私が見つけた問題はパフォーマンスです:テーブル全体から2カウント(*)。また、これら 2 つのテーブル全体の和集合です。

私がテストできるより良い代替アプローチで考えていますか?

4

1 に答える 1

0

次のように実行できます。

SELECT 
    u.*,
    r.shop_id,
    IFNULL(COUNT(DISTINCT r.id), 0) AS num_reservations,
    IFNULL(COUNT(DISTINCT o.id), 0) AS num_orders
FROM users u 
    LEFT JOIN reservarions r ON r.user_id = u.id
    LEFT JOIN shop_orders o ON o.user_id = u.id
GROUP BY u.id
HAVING num_reservations + num_orders > 0

別の方法は、より速いはずです:

SELECT 
    u.*,
    r.shop_id,
    IFNULL(COUNT(DISTINCT r.id), 0) AS num_reservations,
    IFNULL(COUNT(DISTINCT o.id), 0) AS num_orders
FROM users u 
    LEFT JOIN reservarions r ON r.user_id = u.id
    LEFT JOIN shop_orders o ON o.user_id = u.id
WHERE r.id IS NOT NULL OR o.id IS NOT NULL
GROUP BY u.id

ユーザーとユーザーが使用したスト​​アの両方で分割する必要がある場合は、GROUP BY u.id, r.shop_id.

于 2013-04-21T10:02:49.420 に答える