MySQL JOIN "WHEN"- 这样的事情可能吗?

标签 mysql sql join

背景:

  • 我正在运行一个查询,该查询获取客户在上个月订购的总小部件链轮小玩意<
  • 我还有一个总订单列,它运行一个子查询来计算该月的每个订单
  • 我在子查询中执行“总订单”而不是仅添加三列的原因是因为我还为前两列添加了另外两列“总订单”月
  • 我有一个用于存储财务记录的订单表,以及用于存储小部件链轮实际产品详细信息的单独表小玩意

问题:

  • 有时,小部件可能会被“半删除”(不要问!) - 它有订单记录,但没有相应的小部件记录
  • 我不想将其计入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/

相关文章:

sql优化搜索多对多

mysql - 小时开始和结束时间的选择语句

java - 如何使用 Java、AJAX 使用 Rest Web 服务从 MySQL 数据库检索数据并放置在 HTML 表单中

mysql - Perl TLS1.2 到 MySql Db

mysql - 需要在两个表之间进行 SQL 连接并需要比较多个不同的行

php - 三个表之间的内部连接以获取信息

sql - 一个表中的每一行的 PostgreSQL 连接另一个表中的所有行

mysql - subselect sql 查询不适用于 mysql 4

mysql - 用不同的值更新表的列

mysql - 计数查询花费的时间太长 - 已超过 24 小时