与子查询的外部联接更改 mysql 中的行数

Outer join with a subquery changes the count of rows in mysql

SELECT COUNT(1)
FROM erp.cir_order
LEFT JOIN
(
    SELECT increment_id
    FROM magento.sales_flat_order sfo
    JOIN Erp.cir_order co
        ON co.order_num = sfo.increment_id
    WHERE co.status LIKE '3' AND
          DATE(SFO.created_at) >= '2016-02-01' AND
          DATE(SFO.created_at) <= '2016-06-31'
) AS ch
 ON 
cir_order.order_num = sq.increment_id
    WHERE cir_order.status LIKE '3' AND
          cir_order.order_num = ch.increment_id 

为什么 count(1) 会改变 "total" 外部查询返回的记录数,并改变内部查询的条件?

因为我使用的是左外部连接,所以我不明白为什么从子查询中过滤掉 incrementId 会改变外部查询返回的记录数? EVent 如果我在加入条件中使用 incrementId,那是左联接,我的意思是我需要来自 cir_order table 的所有内容,其中状态为 LIKE '3'.

(我故意将它用作子查询)。只是不确定为什么它会像这里那样。

我能得到一些帮助吗?

编辑:

我的问题是如何获取外部查询返回的记录总数,而不关心因 ON 子句中的条件而过滤的记录。我相信我们为此使用外部连接?这就是我尝试使用的。我的意思是,当我说 LEFT OUTER JOIN 时,即使 order_num 没有找到与 increment_id 的匹配项,也请忽略,考虑到 order_num 并给我总行数

EDit2:我的原始查询如下所示:

SELECT count(1) as TotalCirOrders, sq.statusDifferentCount as faultCount
FROM 
Erp.cir_order corder
left JOIN 
(
SELECT count(1) over() as statusDifferentCount, sfo.created_at as createdAt, sfo.increment_id as incrementId
FROM 
Magento.sales_flat_order sfo
LEFT JOIN 
Erp.cir_order cir_order
ON
cir_order.order_num = sfo.increment_id
where
cir_order.status ='3'
AND
sfo.status NOT IN ('refund', 'partial_refund', 'exchange', 'refund_cash', 'partial_refund_cash', 'refund_points')
AND
TO_DATE(SFO.created_at) >= '2016-02-01'
AND
TO_DATE(SFO.created_at) <= '2016-06-31'
) 
AS sq
ON
corder.order_num = sq.incrementId
where
corder.status ='3'
GROUP BY statusDifferentCount;

编辑 3:我需要计算 order_num 和 increment_id 的数量。虽然条件不同。我只从 sales_flat_order table 获取日期字段,所以在业务术语中,我需要计算给定范围内我们 "created" 的 cir order_num,然后我需要计算另一件事计数是 "number of increment id, created in the given range, with status i.e NOT IN the mentioned list"

子查询returns多条同值记录为increment_id时计数可以不同。

LEFT JOIN 也有一个问题:要使 LEFT JOIN 按预期工作(与 INNER JOIN 不同),您不能对加入的 [=40] 设置任何条件=] 在 WHERE 子句中,因为这实际上会将 LEFT JOIN 变成 INNER JOIN (除非你有一个 IS NULL 条件:这是有道理的)。在您的查询中,这发生在这里:

LEFT JOIN Erp.cir_order cir_order
       ON cir_order.order_num = sfo.increment_id
where     cir_order.status ='3'

您可以通过将 WHERE cir_order.status ='3' 条件移动到 ON 子句中并仅计算 cir_order.order_num:

的不同值来解决上述问题
SELECT COUNT(DISTINCT cir_order.order_num)
... etc.

其他计数,即那些 increment_idstatus 额外条件约束的计数,你可以通过将该条件从 WHERE 子句移到 CASE ... WHEN ... THEN increment_id END 构造中并对其执行计数来获得:

SELECT     count(DISTINCT cir_order.order_num) as TotalOrders,
           count(DISTINCT 
              CASE WHEN sfo.status NOT IN ('refund', 'partial_refund', 'exchange', 
                                           'refund_cash', 'partial_refund_cash',
                                           'refund_points') 
                   THEN increment_id 
              END) as statusDifferentCount
FROM       Magento.sales_flat_order sfo
INNER JOIN Erp.cir_order cir_order
      ON   cir_order.order_num = sfo.increment_id
     AND   cir_order.status ='3'
WHERE      to_date(sfo.created_at) BETWEEN '2016-02-01' AND '2016-06-31'

一个解决方案是用

简单地包装整个查询

SELECT COUNT(*) FROM (your query here)