【问题标题】:SQL JOIN omits some fieldsSQL JOIN 省略了一些字段
【发布时间】:2022-01-16 00:04:26
【问题描述】:

我有以下表格:

Product_T 带列:
ProductID,
ProductDescription

OrderLine_T 与列:
OrderID,
ProductID,
OrderedQuantity

Order_T 带列:
OrderID,
CustomerID,

Customer_T 带列:
CustomerID,
CustomerName

我想列出产品 ID 和描述,以及购买该产品最多的客户的客户 ID 和名称,并显示该客户订购的总数量。

我想出了以下查询,列出每个订单的最大数量产品:

SELECT o1.OrderID, o1.ProductID, SUM(o1.OrderedQuantity) AS A
FROM OrderLine_T o1
GROUP BY
  o1.ProductID,
  o1.OrderID
HAVING SUM(o1.OrderedQuantity) = (
    SELECT MAX(s.d)
    FROM (
        SELECT
          o1.OrderID,
          o1.ProductID,
          SUM(o1.OrderedQuantity) AS d
        FROM OrderLine_T o1
        GROUP BY
          o1.ProductID,
          o1.OrderID
    ) s
    WHERE o1.ProductID = s.ProductID
)

这给了我正确的输出:

50  20  1
48  17  5
32  14  10
59  13  2
1   10  9
2   8   2
69  7   4
4   6   3
32  5   10
55  4   2
2   3   12
1   2   18
26  1   5

但是,当我尝试将它与其他表连接时,我可以选择CustomerNameCustomerID,如下所示:

SELECT
  o1.ProductID,
  s.CustomerName,
  s.CustomerID,
  SUM(o1.OrderedQuantity) AS A
FROM OrderLine_T o1
INNER JOIN (
    SELECT
      c1.CustomerName,
      c1.CustomerID,
      p1.ProductID
    FROM Product_T p1
    INNER JOIN OrderLine_T o3 ON p1.ProductID = o3.ProductID 
    INNER JOIN Order_T o2 ON o3.OrderID = o2.OrderID
    INNER JOIN Customer_T c1 ON o2.CustomerID = c1.CustomerID
) s ON s.ProductID = o1.ProductID
GROUP BY
  o1.ProductID,
  s.CustomerName,
  s.CustomerID
HAVING SUM(o1.OrderedQuantity) = (
    SELECT MAX(s.d)
    FROM (
        SELECT
          o1.OrderID,
          o1.ProductID,
          SUM(o1.OrderedQuantity) AS d
        FROM OrderLine_T o1
        GROUP BY
          o1.ProductID,
          o1.OrderID
    ) s
    WHERE o1.ProductID = s.ProductID
) ;

输出缩小到:

17  Contemporary Casuals    1   5
8   Home Furnishings        3   2
7   Eastern Furniture       4   4
10  Eastern Furniture       4   9
20  Dunkins Furniture       8   1
13  Ikards                  13  2

为什么会这样?

【问题讨论】:

  • 基本格式和对空格的良好使用不会出错。请添加示例数据和预期输出。
  • 请发布您的完整 CREATE TABLE 声明。另外,为什么你的表名有_T 后缀?您不应该使用 Systems Hungarian notation at all(它不再是 1970 年代了),尤其是不使用数据库对象,因为(例如)视图和基表是 意味着 i> 可以互换。

标签: sql sql-server tsql


【解决方案1】:

您似乎应该在这里使用窗口函数,例如ROW_NUMBER,以及条件聚合

SELECT
  o.ProductID,
  p.Description,
  CustomerID = MAX(CASE WHEN o.rn = 1 THEN c.CustomerID END),
  CustomerName = MAX(CASE WHEN o.rn = 1 THEN c.CustomerName END),
  SUM(CASE WHEN o.rn = 1 THEN o.TotalQty END) AS QtyForTopCustomer
  SUM(o.TotalQty) AS TotalQty
FROM (
    SELECT
      o.ProductID,
      o.CustomerID,
      TotalQty = SUM(oi.OrderedQuantity),
      rn = ROW_NUMBER() OVER (PARTITION BY oi.ProductId ORDER BY SUM(oi.OrderedQuantity) DESC)
    FROM OrderLine_T ol
    INNER JOIN Order_T o ON o.OrderID = ol.OrderID
    GROUP BY
      o.ProductID,
      o.CustomerID
) o
INNER JOIN Customer_T c ON c.CustomerID = o.CustomerID
INNER JOIN Product_T p ON p.ProductID = ol.ProductID
GROUP BY
  o.ProductID,
  p.Description;

如果您想要该客户的数据,则可以删除条件聚合并仅按行号过滤

SELECT
  o.ProductID,
  p.Description,
  o.CustomerID,
  o.CustomerName,
  o.TotalQty
FROM (
    SELECT
      p.ProductID,
      p.Description,
      o.CustomerID,
      TotalQty = SUM(oi.OrderedQuantity),
      rn = ROW_NUMBER() OVER (PARTITION BY oi.ProductId ORDER BY SUM(oi.OrderedQuantity) DESC)
    FROM OrderLine_T ol
    INNER JOIN Order_T o ON o.OrderID = ol.OrderID
    GROUP BY
      p.ProductID,
      p.Description,
      o.CustomerID
) o
INNER JOIN Customer_T c ON c.CustomerID = o.CustomerID
INNER JOIN Product_T p ON p.ProductID = ol.ProductID
WHERE o.rn = 1;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多