有几十个线程有这个标题,但我发现的似乎都没有帮助。
我有一个由两个表组成的查询:表客户和表事务
每个客户在交易表中可以有多个条目。我想做的是在给定的时间范围内(假设日期在交易表中跟踪),在客户表中找到每个客户,并从交易表中为该客户找到三个不同的计算。第一个数字计算发出的报价数量,第二个数字计算订单数量,第三个数字是未转化为订单的报价总数。计算本身并不重要,因为它与这个问题的解决方案有关。
我觉得有某种类型的联接我没有正确地利用它来导出正确的值,但这是我迄今为止所做的(简化)。
SELECT Customer.CustomerID, Count(TransactionAlias1.*), Count(TransactionAlias2.*), Count(TransactionAlias3.*)
FROM Customer
LEFT JOIN (SELECT * FROM Transactions WHERE [...]) TransactionAlias1 ON
TransactionAlias1.CustomerID = Customer.CustomerID
LEFT JOIN (SELECT * FROM Transactions WHERE [...]) TransactionAlias2 ON
TransactionAlias2.CustomerID = Customer.CustomerID
LEFT JOIN (SELECT * FROM Transactions WHERE [...]) TransactionAlias3 ON
TransactionAlias3.CustomerID = Customer.CustomerID
GROUP BY Customer.CustomerID
奇怪的是,只有前两个内部联接会为前两个Count生成正确的值。添加第三个内部联接将使其他值无效。在每个内部联接中单独运行select语句会产生正确的计数。
如有任何帮助,我们将不胜感激。如果你们中的任何人知道另一篇StackOverflow文章解决了同样的问题,请告诉我。
这并不奇怪——三个子查询中的每个子查询都有不同的WHERE过滤器,所以除非每个客户每个子查询至少有一个事务,否则内部联接将产生你意想不到的结果。
您应该使用LEFT JOIN为所有客户接收正确的结果。或者,你可以这样做:
SELECT Customer.CustomerID, sum(Count1) as Count1, sum(Count2) as Count2, sum(Count3) as Count3
FROM Customer
LEFT JOIN (
SELECT CustomerID,
case when ... then 1 else 0 end as Count1,
case when ... then 1 else 0 end as Count2,
case when ... then 1 else 0 end as Count3
FROM Transactions
) s Txn
on txn.CustomerID = Customer.CustomerID
GROUP BY Customer.CustomerID
在我看来,第二次加入应该通过计数。
将条件从联接条件移动到case
表达式怎么样?
select Customer.CustomerId
, count(case when [...] then 1 else null end) as Quote_Count
, count(case when [...] then 1 else null end) as Order_count
, count(case when [...] then 1 else null end) as Quote_not_order_count
from Customer
left join Transactions
on Transactions.CustomerId = Customer.CustomerId