多个COUNT / GROUP BY语句返回意外结果

时间:2016-09-28 11:05:05

标签: sql postgresql

查询postgreSQL 9.4 db,我希望能够看到每个客户根据以前的订单与每个员工进行交互的频率。我的目标是以下列格式检索数据:

CUSTOMER     EMPLOYEE    INTERACTIONS   CUSTOMER_TOTAL
Customer1    EmployeeA             30               50
Customer1    EmployeeB             20               50
Customer2    EmployeeD              6               15
Customer2    EmployeeA              6               15
Customer2    EmployeeC              3               15

...我在客户和员工的每个组合的结果中都有一个单独的记录(假设两者之间至少发生了一个订单)。

我想要包含一个列,其中包含客户与每个员工之间的订单数量(请参阅上面的第3列),以及另一列,其中包含每个客户的总订单总数(请参阅上面的第4列)。

我写了以下查询:

SELECT customer.name as Customer, employee.name as Employee, 
  SUM(CASE WHEN orders.employee_id = employee.id AND orders.customer_id = customer.id THEN 1 ELSE 0 END) AS Interactions,
  SUM(CASE WHEN orders.customer_id = customer.id THEN 1 ELSE 0 END) AS Customer_Total

FROM tblcustomer customer
  JOIN tblorder orders ON orders.customer_id = customer.id
  LEFT JOIN tblemployee employee ON employee.id = orders.employee_id

GROUP BY customer.name, employee.name

ORDER BY Customer, Interactions DESC; 

返回了以下结果:

CUSTOMER     EMPLOYEE    INTERACTIONS   CUSTOMER_TOTAL
Customer1    EmployeeA             30               30
Customer1    EmployeeB             20               20
Customer2    EmployeeD              6                6
Customer2    EmployeeA              6                6
Customer2    EmployeeC              3                3

除最终列外,所有行/列都按预期显示。它只返回了员工也匹配的订单,而不是每个客户的总订单数。我哪里出错?

2 个答案:

答案 0 :(得分:0)

我认为你应该在这里使用LEFT JOIN

SELECT customer.name as Customer,
       employee.name as Employee, 
       SUM(CASE WHEN orders.employee_id = employee.id AND
                       orders.customer_id = customer.id
                  THEN 1 ELSE 0 END) AS Interactions,
       SUM(CASE WHEN orders.customer_id = customer.id
                  THEN 1 ELSE 0 END) AS Customer_Total
FROM tblcustomer customer
LEFT JOIN tblorder orders
    ON orders.customer_id = customer.id
LEFT JOIN tblemployee employee
    ON employee.id = orders.employee_id
GROUP BY customer.name,
         employee.name
ORDER BY Customer, 
         Interactions DESC;

我的预感是你的INNER JOIN正在筛选出包含客户总数的记录。使用LEFT JOIN即可保留这些记录。

答案 1 :(得分:0)

与tblEmployee的一个左联接将执行该任务。与tblEmployee的内部联接将仅筛选并获取客户与每个员工之间订单数量的记录。

   SELECT customer.name as Customer,
   employee.name as Employee, 
   SUM(CASE WHEN orders.employee_id = employee.id AND
                   orders.customer_id = customer.id
              THEN 1 ELSE 0 END) AS Interactions,
   SUM(CASE WHEN orders.customer_id = customer.id
              THEN 1 ELSE 0 END) AS Customer_Total
   FROM tblcustomer customer
   JOIN tblorder orders
   ON orders.customer_id = customer.id
   LEFT JOIN tblemployee employee
   ON employee.id = orders.employee_id
   GROUP BY customer.name,
     employee.name
   ORDER BY Customer, 
     Interactions DESC;