背景:
- 我正在运行一个查询,该查询获取客户在上个月订购的总小部件、链轮和小玩意<
- 我还有一个总订单列,它运行一个子查询来计算该月的每个订单
- 我在子查询中执行“总订单”而不是仅添加三列的原因是因为我还为前两列添加了另外两列“总订单”月
- 我有一个用于存储财务记录的订单表,以及用于存储小部件、链轮和实际产品详细信息的单独表小玩意
问题:
- 有时,小部件可能会被“半删除”(不要问!) - 它有订单记录,但没有相应的小部件记录
- 我不想将其计入Total Widgets 列 - 这很简单,因为我只需执行
JOIN
- 但是,我也不想将其计入总订单列中...
我当前的查询如下所示:Total Widgets:
SELECT
COUNT(orders.id)
FROM orders
JOIN widgets ON widgets.id = orders.item_id
WHERE orders.product_id = 1 -- Product ID 1 is a Widget
AND orders.date BETWEEN "2014-09-01 00:00:00" AND "2014-09-30 23:59:59"
因此,这将获得所有“准确”的小部件,以及完整的小部件
表记录。
这是我当前对总订单的查询:
SELECT
COUNT(orders.id) AS count
FROM orders
JOIN widgets ON widgets.id = orders.item_id AND orders.product_id = 1
WHERE orders.date BETWEEN "2014-09-01 00:00:00" AND "2014-09-30 23:59:59"
所以我的想法是,只有当订单的 product_id
为 1 时,上述查询才应该 JOIN
。但是,它 JOIN
在每个案例。这意味着,如果我们订购了 10 个小部件(其中 2 个已被删除一半)、5 个链轮和 5 个小玩意,则不会显示 18 个订单,而是只显示 8 个。更改为 LEFT JOIN
显示20,还是错误,应该是18。
希望以上内容有意义 - 提前致谢。
最佳答案
好吧...直接连接不起作用,因为您过滤了 orders.product_id = 1
因此它不会计算链轮或小玩意。只是小部件。如果您删除了 2 个一半,但记录了 10 个……8 就是正确答案。 left outer join
让它加入 product_id <> 1
的行也是如此,因此来自 orders
的所有行(其中包含小部件、链轮、小发明的订单记录 - 一半删除或未删除)。但这也允许那两行被删除一半。
为什么不直接连接呢?如果你想要答案18,只需将订单和产品连接起来并计算即可。不要仅过滤小部件。如果您不想删除一半,请不要做左外。
create table product (
product_id int,
product_name varchar(20)
);
insert into product values (1,'widget');
insert into product values (2,'sprocket');
insert into product values (3,'gizmo');
create table `order` (
order_id int,
widget_id int
);
insert into `order` values (1,1);
insert into `order` values (1,2);
insert into `order` values (1,3);
insert into `order` values (1,4); -- half deleted
insert into `order` values (2,1);
insert into `order` values (2,2);
insert into `order` values (3,3);
insert into `order` values (3,4); -- half deleted
insert into `order` values (4,4); -- half deleted
select o.order_id, count(*)
from `order` as o
join product as p
on o.widget_id=p.product_id
group by o.order_id
+----------+----------+
| order_id | count(*) |
+----------+----------+
| 1 | 3 |
| 2 | 2 |
| 3 | 1 |
+----------+----------+
3 rows in set (0.00 sec)
<小时/>
mysql> select o.order_id,
-> p.product_name,
-> (case when p.product_id is null
-> then 'half_deleted' else '' end) as half_deleted
-> from `order` as o
-> left outer join product as p
-> on o.widget_id=p.product_id
-> order by order_id ;
+----------+--------------+--------------+
| order_id | product_name | half_deleted |
+----------+--------------+--------------+
| 1 | gizmo | |
| 1 | NULL | half_deleted |
| 1 | widget | |
| 1 | sprocket | |
| 2 | widget | |
| 2 | sprocket | |
| 3 | gizmo | |
| 3 | NULL | half_deleted |
| 4 | NULL | half_deleted |
+----------+--------------+--------------+
关于MySQL JOIN "WHEN"- 这样的事情可能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26339767/