【问题标题】:Query to list customers of a shop, with two different orders table查询列出一家商店的客户,有两个不同的订单表
【发布时间】:2013-04-21 21:37:36
【问题描述】:

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

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

【问题讨论】:

  • 什么是样本数据和期望的输出?

标签: mysql sql


【解决方案1】:

你可以这样做:

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

【讨论】:

  • 正在工作,但也发现性能问题:2 x count(*) 和一个需要在整个用户表中操作的“有”...
  • 添加了另一个版本,应该更快。
  • @sashkello 。 . .如果 OP 想要通过 shop_id 过滤,那么它也应该在 group by 子句中。一个用户可能是不止一家商店的顾客。
  • @GordonLinoff,是的,您可能是对的 - 但这不是我从问题中提供的示例查询中得到的。不过,这很容易解决……
猜你喜欢
  • 2021-03-23
  • 1970-01-01
  • 2021-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多