每个客户花费的SQL总数

时间:2014-05-02 13:14:30

标签: sql sql-server sqlite

这是我第一次在这里问一个问题,我通常可以从搜索中找到我需要的东西,不过这次我被困住了,我希望这里有人可以提供帮助。

这是要点。我为一家美发工作室创建了一个数据库。有五张桌子。这个问题唯一涉及的是Customers表(存储客户详细信息),ProductSales表(关于每个产品销售的商店详细信息,以及HairCuts表,存储有关每个剪切的详细信息。

我需要一个查询,列出客户表中每个客户的头发削减和产品所花费的总额。

我有两个单独的查询可以正常工作。每个人计算每个顾客为削减头发或产品所花费的总金额。我需要以某种方式将这些组合成一个能显示总数的。

SELECT c.customer_ID, c.first_Name, c.last_name, 
SUM(hc.cost) AS hc_sales_total
FROM Customers c, HairCuts hc
WHERE c.customer_ID = hc.customer_ID
GROUP BY c.customer_ID;

SELECT c.customer_ID, c.first_Name, c.last_name, 
SUM(ps.cost) AS ps_sales_total
FROM Customers c,ProductSales ps
WHERE c.customer_ID = ps.customer_ID
GROUP BY c.customer_ID;

我相信我所遇到的问题源于这样一个事实,即虽然所有顾客至少购买了一次剪发,但并非所有顾客都购买了产品。无论如何,任何帮助将不胜感激。

5 个答案:

答案 0 :(得分:4)

UNION你的两个问题在一起。

然后你会得到一张包含所有费用的表格。

从那时起,您可以将其视为新查询的来源,以总计这些结果

SELECT customer_ID, first_name, last_name, sum(hc_sales_total) as totalsales
FROM
(
    SELECT c.customer_ID, c.first_Name, c.last_name, 
    SUM(hc.cost) AS hc_sales_total
    FROM Customers c 
         INNER JOIN HairCuts hc
         ON c.customer_ID = hc.customer_ID
    GROUP BY c.customer_ID

    UNION ALL

    SELECT c.customer_ID, c.first_Name, c.last_name, 
    SUM(ps.cost) AS ps_sales_total
    FROM Customers c
         INNER JOIN ProductSales ps
         ON c.customer_ID = ps.customer_ID
    GROUP BY c.customer_ID
) sales
GROUP BY customer_ID, first_name, last_name

当然,内部分组是多余的,所以

SELECT customer_ID, first_name, last_name, sum(cost) as totalsales
FROM
(
    SELECT c.customer_ID, c.first_Name, c.last_name, hc.cost
    FROM Customers c 
         INNER JOIN HairCuts hc
         ON c.customer_ID = hc.customer_ID

    UNION ALL

    SELECT c.customer_ID, c.first_Name, c.last_name, ps.cost
    FROM Customers c
         INNER JOIN ProductSales ps
         ON c.customer_ID = ps.customer_ID
) sales
GROUP BY customer_ID, first_name, last_name

答案 1 :(得分:1)

如果您想要所有三个总和,可以使用union all / group by方法执行此操作:

SELECT c.customer_ID, c.first_Name, c.last_Name,
       SUM(hp.hc_sales) as hp.hc_sales_total, SUM(hp.ps_sales) as hp.ps_sales_total,
       SUM(hp.hc_sales_total + hp.ps_sales_total) as Total
FROM ((SELECT hc.customer_ID, hc.cost AS hc_sales, 0 as ps_sales
       FROM HairCuts hc 
      ) UNION ALL
      (SELECT ps.customer_ID, 0, ps.cost AS ps_sales
       FROM ProductSales ps
      )
     ) hp JOIN
     Customers c
     on c.customer_ID = hp.customer_ID
GROUP BY c.customer_ID, c.first_Name, c.last_Name;

请注意此查询与您的查询不同的方式:

  1. 已经考虑了两个连接,因此每个子查询只能处理一个表。
  2. union all使用显式join语法后的联接,条件符合on子句。
  3. 只有一个聚合。

答案 2 :(得分:0)

你有没有试过这样的事情:

SELECT c.customer_ID, c.first_Name, c.last_name, 
SUM( isnull( hc.cost,0) + isnull(ps.cost,0) ) AS hc_pc_sales_total
FROM Customers c, HairCuts hc, ProductSales ps
WHERE c.customer_ID = hc.customer_ID AND
      c.customer_ID = ps.customer_ID
GROUP BY c.customer_ID;

我不知道你使用的是哪个数据库,但请不要忘记使用'ISNULL'来处理'null'值。

有关ISNULL函数,请参阅http://www.w3schools.com/sql/sql_isnull.asp

答案 3 :(得分:0)

您需要使用外部联接以确保所有客户都在联接表中表示。这是您修改的第二个查询:

SELECT
    c.customer_ID,
    c.first_Name,
    c.last_name,
    COALESCE(SUM(ps.cost), 0) AS ps_sales_total
FROM
    Customers AS c
    LEFT JOIN ProductSales AS ps ON c.customer_ID = ps.customer_ID
GROUP BY
    c.customer_ID

另请注意,我使用COALESCE确保SUM的结果为零而不是NULL。

顺便说一句,我个人不喜欢用于连接表的逗号语法(FROM c, ps)。我更喜欢使用显式语法(FROM c JOIN ps ON ...)。在某种程度上,这是因为我认为最好将连接逻辑放在FROM子句中,而不是将它与WHERE子句组合。

另外,为什么first_NameNlast_namen

关于组合两个查询的结果,您可以采用多种方法。您可以在子查询中使用union,然后使用GROUP BY使用GROUP,如podiluska所建议的那样。或者,您可以为customers表中的每一行选择子查询的结果:

SELECT
    (
        SELECT COALESCE(SUM(hc.cost), 0)
        FROM HairCuts AS hc
        WHERE hc.customer_ID = c.customer_ID
    ) + (
        -- similar to above
    ) AS AmountSpent
FROM
    Customers c

答案 4 :(得分:0)

就个人而言,我更喜欢预先聚合到新的表引用中:

SELECT Customers.customer_Id, Customer.first_Name, Customer.last_Name,
       COALESCE(HairCuts.cost, 0) + COALESCE(ProductSales.cost, 0) as totalCost
FROM Customers
LEFT JOIN (SELECT customer_Id, SUM(cost) AS cost
           FROM HairCuts
           GROUP BY customer_Id) HairCuts
       ON HairCuts.customer_Id = Customers.customer_Id
LEFT JOIN (SELECT customer_Id, SUM(cost) AS cost
           FROM ProductSales
           GROUP BY customer_Id) ProductSales
       ON ProductSales.customer_Id = Customers.customer_Id

(未经过测试,因为我没有基于它的数据。但是应该在任何RDBMS中工作)