【问题标题】:Join when table A has duplicate records表A有重复记录时加入
【发布时间】:2012-04-13 09:51:12
【问题描述】:

我在过去 2 小时内读到的所有关于 SQL Server 和联接的内容都快要爆炸了。

tbl_customers
-------------
IPaddress
CustomerID


tbl_purchases
-------------
OrderID (pkey)
CustomerID
OrderTotal

我想获取每个 IP 地址的总购买量。 tbl_customers 表中有更多列,因此存在重复的 (IPaddress, CustomerID) 行。我使用了以下查询:

SELECT DISTINCT IPaddress, SUM(OrderTotal) FROM tbl_customers a
INNER JOIN tbl_purchases b ON a.CustomerID = b.CustomerID
GROUP BY IPaddress;

但它会从 tbl_customers 检索重复的行,并导致 sum 函数多次计算同一购买。我究竟做错了什么?效率并不是真正的问题,因为我正在处理低于 10K 的记录。

【问题讨论】:

  • 也许 IP 地址应该在 tbl_purchases 中。

标签: sql-server join duplicates sum


【解决方案1】:
SELECT tc.IPaddress,SUM(tp.OrderTotal)
FROM (SELECT DISTINCT IPaddress,CustomerID FROM tbl_customers) tc,
     tbl_purchases tp
WHERE tc.CustomerID = tp.CustomerID
GROUP BY tc.IPaddress;

SELECT tc.IPaddress,SUM(tp.OrderTotal)
        FROM (SELECT DISTINCT IPaddress,CustomerID FROM tbl_customers) tc
              INNER JOIN 
             tbl_purchases tp
             ON   tc.CustomerID = tp.CustomerID
 GROUP BY tc.IPaddress;

【讨论】:

  • 为什么要使用逗号而不是 JOIN (INNER/LEFT) 语法来连接表?
  • @jlarkins 使用逗号而不是 JOIN 只是语法的一种不同方式。如果我记得正确的 table1、table2 和 using WHERE 语句是在 SQL 中引入 INNER JOIN 之前。因此,您可以使用逗号分隔并将连接子句移动到 WHERE 语句,或者您可以根据需要使用 INNER JOIN。
  • 如果客户有多个 IP,此报告的总购买量将高于 tbl_purchases 中实际存在的购买量。
【解决方案2】:

首先,听起来您的数据库未标准化。如果您有一个客户表,并且多行具有相同的 CustomerId,那么该表是否有主键或者这应该是识别客户的键?

【讨论】:

  • tbl_customers 不适合这样持有客户,我的示例已针对公开发布进行了清理。
【解决方案3】:

我想获取每个 IP 地址的总购买金额。

使用您当前的架构,如果客户从多个 IP 进行购买,那么您不可能获得这样的金额(除非您想对该客户的所有 IP 或其他东西的金额进行平均)。也许IPaddress 应该在tbl_purchases 中。

【讨论】:

  • 是的,我意识到这一点,但是当我从多个其他来源编译这些表中的数据时,我没有这个特权。至少,我还没想好怎么做。
  • 您有拥有多个 IP 的客户吗?如果是这样,你不能满足规定的要求,或者你必须选择一个 IP 来应用销售,或者平均它们等等。
  • 如果客户有多个 IP,我想计算两个 IP 的订单总数。因此,如果 Bob 有来自 192.168.1.1 的 500 美元的订单和来自 192.168.1.2 的 300 美元的订单,我希望看到与每个 IP 相关联的 800 美元。
猜你喜欢
  • 1970-01-01
  • 2019-10-04
  • 2017-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多