【问题标题】:SQL Query for three tables with calculation三个表的 SQL 查询与计算
【发布时间】:2013-12-03 12:07:39
【问题描述】:

我收到了一个面试问题,但我无法解决。我不在SQL领域,更多的是展示解决问题的能力而不是SQL能力。不过我还是想弄清楚!

它在 MS SQL 服务器中,但通用 SQL 答案是可以接受的。

我有 3 个表:Sales、Customers、Products 和表中的 NO NULL 值。

客户:Customer_ID、Customer_Name

产品:Product_ID、Product_Price

销售额:Customer_ID、Product_ID、Number_Purchased

他们希望我将支付最多的客户展示给支付最少的客户。

所以我需要将客户的客户 ID 链接到销售中的客户 ID,然后将销售额链接到产品价格并计算价格 * 购买数量并将其分配给正确的人。

我当时尝试过这样的事情:(显然是错误的)

SELECT Customers.Customer_ID, Customers.Customer_Name, SUM(Sales.Number_Purchased *Products.Product_Price) as Total
FROM (Customers 
INNER JOIN Products 
ON Customers.Customer_ID = Products.Customer_ID)
INNER JOIN Sales ON 
Products.Product_ID = Sales.Product_ID
GROUP BY Customers.Customer_ID, Customers.Customer_Name

显然我不擅长 SQL,但如果有人能在正确的方向上推动我解决这个问题(第二次面试将在几个小时内完成!)我将不胜感激!我已经把自己打成结了。

【问题讨论】:

  • 我了解这些客户互相卖东西。所以应该有另一个表或另一个字段来定义哪个产品属于哪个客户。有时他们会寻找问题而不是答案。
  • 对不起,我应该假设公司正在销售。每个客户从一家公司购买不同的产品。他们不互相出售。我认为我的垃圾代码可能会造成混乱。这是公司数据库。他们想知道他们的哪个客户花的钱最多!不过,我今天会在第二次面试中问这个问题,因为这是一个聪明的问题,他们可能想把我赶走!

标签: sql sql-server


【解决方案1】:

如果您希望列表按付费最高到最低排序,请添加:

ORDER BY SUM(Sales.Number_Purchased * Products.Product_Price) DESC

此外,您必须更改一些 JOIN 条件,因为您没有在表之间建立正确的连接。

由于您是在 MS-ACCESS 中执行此操作,因此您必须用括号括起来 JOINS

应该是:

SELECT Customers.Customer_ID, 
       Customers.Customer_Name,
       SUM(Sales.Number_Purchased * Products.Product_Price) AS Total
FROM ((Customers 
INNER JOIN Sales ON Sales.Customer_ID = Customers.Customer_ID)
INNER JOIN Products ON Sales.Product_ID = Products.Product_ID)
GROUP BY Customers.Customer_ID, Customers.Customer_Name
ORDER BY SUM(Sales.Number_Purchased * Products.Product_Price) DESC

【讨论】:

  • 它给了我一个缺少运算符的语法错误,但是我可能命名错误。我现在要调查。
  • @RossC。我看到了错误。它在 JOIN 中。您加入了错误的列。立即尝试
  • 我正在 Access 中进行测试,所以这可能是问题所在。我仍然收到语法错误,第一个内部连接上缺少运算符。以下所有解决方案都给出错误。
  • 在访问中,您必须在连接周围加上括号。我编辑了我的答案
  • 这是标准 SQL。它可以在每个 DBMS 中工作,但是访问有括号的小技巧:)
【解决方案2】:

我希望通过以下步骤来解决这个问题。

首先,找出所有客户每次购买的总和。

SELECT Customer_ID, SUM (Sales.Number_Purchased * Products.Product_Price)
FROM Sales
INNER JOIN Products ON Products.Product_ID = Sales.Product_ID
GROUP BY Customer_ID

然后我们想知道客户的姓名。所以我们将内部加入Customes 表。

SELECT Customer_ID, Customer_Name, SUM (Sales.Number_Purchased * Products.Product_Price)
FROM Sales
INNER JOIN Products ON Products.Product_ID = Sales.Product_ID
INNER JOIN Customers ON Customers.Customer_ID = Sales.Customer_ID
GROUP BY Customer_ID

最后,您可以执行 ORDER BY 语句来找出支付最多和最少的人。

请注意,在您的代码中,不允许 Products.Customer_ID,因为 Customer_ID 不是 Products 表中的列之一。

编辑 糟糕,我的第二个 SQL 中有一个模棱两可的列。它应该是“SELECT Customers.Customer_ID”,因为列名 Customer_ID 在两个不同的表中使用。

【讨论】:

  • 打破它的好主意。他们可能想要一个查询,但这确实有助于学习概念,非常感谢。
【解决方案3】:

男孩,我一直在你的鞋子里,有一半的时间不允许规范化数据库中的表:(

我很快就看到的任何人都原谅语法错误。但你会明白的:

SELECT Customers.Customer_ID, 
    Customers.Customer_Name, 
    SUM(Sales.Number_Purchased *Products.Product_Price) as Total
FROM Customers
LEFT JOIN SALES
ON customers.customer_ID = Sales.Customer_ID
left JOIN Products
ON  Sales.productid = products.product_ID
Customers.Customer_ID, Customers.Customer_Name
GROUP BY Customers.Customer_ID, Customers.Customer_Name
ORDER BY SUM(Sales.Number_Purchased * Products.Product_Price) DESC

无法检查,但基本上你是对的,但不是在连接上。

内连接只会得到匹配的结果。但是什么都没带的用户呢?它们不会存在于销售部分,因此它们不会存在于您的结果中,这在我从事的工作中是一件坏事,因为他们希望看到所有客户。 这使您可以撤回所有这些,然后如果需要,可以过滤掉空销售额。 通常最好将它们归零,然后您可以提供有关尚未消费的客户的信息。 (添加的信息让他们开心;))

所以,使用左联接,无论花费多少,您都会吸引到每一位客户。 然后将其与产品相匹配,记住您要保留所有销售,并确保丢失数据没有问题,使用另一个左侧。 然后真的只是使用 order by,然后就完成了。

希望对你有帮助

【讨论】:

  • 我认为是 Inner,因为他们说不用担心 NULL 值,但这样会更正确!
  • 这将无法满足如下所述的要求:他们要我将支付最多的客户展示给支付最少的客户。
  • @KMB 哦?为什么不?有什么我想念的吗?
  • 这将为他提供确认的数据,包括没有销售的客户。销售额为空的客户通常被认为是 0 销售额,因此应该包括在内,因为它还提供了附加信息,所以我不明白为什么这不会给他一切?加上更多?原谅无法检查的语法错误,如果这就是你的意思
【解决方案4】:

你错过了两件事。 A) 表之间的链接不正确。跟随关键列是有用的练习 B) 正如 Filipe 指出的那样,ORDER BY 子句进行排序

SELECT 
  Customers.Customer_ID, Customers.Customer_Name, 
  SUM(Sales.Number_Purchased *Products.Product_Price) as Total
FROM Customers 
  -- connect sales to customers
  INNER JOIN Sales ON 
    ON Sales.Customer_ID = Customers.Customer_ID
  -- connect products to sales
 INNER JOIN Products 
   Products.Product_ID = Sales.Product_ID
-- group to deliver an aggregate
GROUP BY Customers.Customer_ID, Customers.Customer_Name
-- sort
ORDER BY SUM(Sales.Number_Purchased * Products.Product_Price) DESC

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多