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 个计数(*)。也是这两个完整表之间的联合。

你认为我可以测试一个更好的替代方法吗?

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 回答