与子查询的外部联接更改 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_id 受 status 额外条件约束的计数,你可以通过将该条件从 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)
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_id 受 status 额外条件约束的计数,你可以通过将该条件从 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)