使用count和if左连接和聚合函数

时间:2012-07-20 21:38:33

标签: mysql aggregate-functions

我编写了一个查询,它将三个表连接到一个客户表,计算各个字段的值,并返回按销售代表细分的销售和收入概览:

SELECT 
    u.id AS `userId`, 
    u.`username`, 
    (SELECT COUNT(*) FROM `SaleSet` s WHERE s.`pitchedBy_id` = `userId` AND s.setCompleteAt BETWEEN '2012-07-02 00:00:00' AND '2012-07-02 23:59:59') AS `transfers`,
    COUNT(c.id) AS `closes`, 
    COUNT(IF(c.saleType_id = 1, 1, NULL)) AS `regS_sales`,
    COUNT(IF(c.saleType_id = 2, 1, NULL)) AS `pd_sales`,
    COUNT(IF(c.saleType_id = 4, 1, NULL)) AS `attempted_sales`,
    COUNT(IF(c.CustomerStatus_id IN (5,6,9,16), 1,NULL)) AS `complete`,
    COUNT(IF(c.CustomerStatus_id IN (8,18), 1,NULL)) AS `canceled`,
    COUNT(IF(c.CustomerStatus_id IN (1,12,13), 1,NULL)) AS `pending`,
    COUNT(IF(c.CustomerStatus_id = 20, 1,NULL)) AS `post_dated`,
    SUM(IF(p.saleType_id = 2, p.`authOnlyAmount`,0)) AS `pdPotRev`,
    #SUM(IF(c.saleType_id = 2 AND t.`captured` = 0, p.`authOnlyAmount`,0)) AS `pdCapRev`,
    SUM(t.amount) AS `fwRevAuthed`,
    SUM(IF(p.saleType_id = 2 AND t.`captured` = 0, t.amount,0)) AS `fwCaptured`
FROM customer c
LEFT JOIN `User` u ON u.id = c.`salesRep_id`
LEFT JOIN `Transaction` t 
    ON t.`customer_id` = c.`id`
    AND t.transactionType = 'Auth'
LEFT JOIN `Purchase` p ON p.`customer_id` = c.`id`
#WHERE c.`salesRep_id` = 10
WHERE c.`activationDate` BETWEEN '2012-07-02 00:00:00' AND '2012-07-02 23:59:59'
GROUP BY u.`id`

为什么此列返回0而不是t.amount:SUM(IF(p.saleType_id = 2 AND t.captured = 0, t.amount,0)) AS fwCaptured的总和?正如你所看到的,我在上面两行完全相同,它工作正常。

以下是结果示例:

userId  username          transfers  closes  regS_sales  pd_sales  attempted_sales  complete  canceled  pending  post_dated  pdPotRev  fwRevAuthed  fwCaptured  
10  doughaase                17       4           3         1                0         4         0        0           0     50.00       298.00          0.00
65  davidgarber              13       5           5         0                0         4         0        0           0      0.00       595.00          0.00
70  morgantaylor              5       2           2         0                0         0         2        0           0      0.00       198.00          0.00
76  shayans                   8       1           0         1                0         1         0        0           0     99.00        99.00          0.00
96  regananson                5       3           3         0                0         3         0        0           0      0.00       248.00          0.00

pdPotRev以完全相同的方式使用完全相同的功能,并且工作正常。

1 个答案:

答案 0 :(得分:2)

对于每个类型2的捕获销售,或许t.amount为0,或者甚至可能是正值和负值。 在上面的字段中,您将对不同的字段求和,因此它返回不同的值是有意义的。您甚至可以从完全不同的表中进行选择。

如果有疑问,请删除总和和分组,然后选择值。您应该能够立即发现问题。

[编辑] 甚至不是这样。 pdPotRev根本不使用p.captured字段。包含相同条件的行是pdCapRev,它被注释掉了。因此,IF(p.saleType_id = 2 AND t.captured最有可能永远不会评估为真。