我需要sql帮助查询: 我想创建一个列出商店顾客的视图。这是一个用户表的选择,它已经进行了一次或多次预订(表预订)或已经进行了一次或多次订购(table 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或num_orders> 0)
我发现的问题是性能:整个表中有2个计数(*)。还有这两个整表之间的联合。
你认为我能测试一种更好的替代方法吗?
答案 0 :(得分: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
。