sql - 如何聚合描述列?

标签 sql sql-server aggregate aggregate-functions

我编写了一个 SQL 查询来计算每个仓库的库存总数,如下所示。

SELECT
  InventoryItem.ItemName as 'Part Number',
  InventoryItemDescription.ItemDescription as 'Description',
  InventoryStockTotal.UnitsInStock as 'In Stock',
  InventoryStockTotal.WarehouseCode AS 'Warehouse',
  InventoryItem.Status,
  InventoryItem.AverageCost AS 'Average Cost',
  (InventoryItem.AverageCost * UnitsInStock) AS 'Stock Value'


FROM dbo.InventoryItemDescription
INNER JOIN dbo.InventoryItem
  ON InventoryItemDescription.ItemCode = InventoryItem.ItemCode
INNER JOIN dbo.InventoryStockTotal
  ON InventoryStockTotal.ItemCode = InventoryItem.ItemCode


这给了我这样的结果


╔═════════════╦═════════════╦══════════╦═══════════════════╦════════╦══════════════╦═════════════╗
║ Part Number ║ Description ║ In Stock ║     Warehouse     ║ Status ║ Average Cost ║ Stock Value ║
╠═════════════╬═════════════╬══════════╬═══════════════════╬════════╬══════════════╬═════════════╣
║         555 ║ FILTER      ║        0 ║ BRISBANE          ║ A      ║ 8.761043     ║ 0           ║
║         555 ║ FILTER      ║      187 ║ MAIN              ║ A      ║ 8.761043     ║ 1638.315041 ║
║         555 ║ FILTER      ║        0 ║ MELBOURNE         ║ A      ║ 8.761043     ║ 0           ║
║         555 ║ FILTER      ║       21 ║ PERTH             ║ A      ║ 8.761043     ║ 183.981903  ║
║         555 ║ FILTER      ║        0 ║ PATTISONS         ║ A      ║ 8.761043     ║ 0           ║
║         555 ║ FILTER      ║       12 ║ QLD Warehouse (1) ║ A      ║ 8.761043     ║ 105.132516  ║
║         555 ║ FILTER      ║       22 ║ SYDNEY            ║ A      ║ 8.761043     ║ 192.742946  ║
╚═════════════╩═════════════╩══════════╩═══════════════════╩════════╩══════════════╩═════════════╝


但是,我正在尝试编写一个查询,该查询将为我提供每个零件号的总计,如下所示(显然,如果我显示所有仓库的总计,仓库代码就会变得多余)

此查询按部件号分组。

╔═════════════╦════════════════╦══════════╦════════╦══════════════╦═════════════╗
║ Part Number ║  Description   ║ In Stock ║ Status ║ Average Cost ║ Stock Value ║
╠═════════════╬════════════════╬══════════╬════════╬══════════════╬═════════════╣
║       555   ║ WIX AIR FILTER ║      242 ║ A      ║ 8.761043     ║ 2120.172406 ║
╚═════════════╩════════════════╩══════════╩════════╩══════════════╩═════════════╝

我能够开始工作的唯一查询是这个

SELECT
  InventoryItem.ItemName as 'Part Number',
  InventoryItem
  SUM(InventoryStockTotal.UnitsInStock) as 'In Stock',
  AVG(InventoryItem.AverageCost) AS 'Average Cost',
  (AVG(InventoryItem.AverageCost) * SUM(InventoryStockTotal.UnitsInStock)) AS 'Stock Value'

FROM dbo.InventoryItemDescription
INNER JOIN dbo.InventoryItem
  ON InventoryItemDescription.ItemCode = InventoryItem.ItemCode
INNER JOIN dbo.InventoryStockTotal
  ON InventoryStockTotal.ItemCode = InventoryItem.ItemCode

  GROUP BY InventoryItem.ItemName

这给了我这个

╔═════════════╦════════════╦══════════════╦═════════════╗
║ Part Number ║  In Stock  ║ Average Cost ║ Stock Value ║
╠═════════════╬════════════╬══════════════╬═════════════╣
║         555 ║ 242.000000 ║ 8.761043     ║ 2120.172406 ║
╚═════════════╩════════════╩══════════════╩═════════════╝

问题

我还需要在结果表中包含项目描述和状态代码等,除非当我尝试将它们添加到选择语句时它会返回错误

Column 'dbo.InventoryItemDescription.ItemDescription' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. I understand the cause of this error because its trying to group a column that doesn't have an aggregate, but how can I get around this? 

理想的解决方案

每个实例的零件号描述都是相同的,有什么方法可以指示 SQL 仅选择描述的第一个实例吗?

** 编辑 2 **

我可以使用SELECT DISTINCT 函数吗?

最佳答案

如果每个部件号的描述始终相同,则无需将其添加到分组依据子句中。

SELECT
  InventoryItem.ItemName as 'Part Number',
  InventoryItemDescription.ItemDescription as 'Description',
  SUM(InventoryStockTotal.UnitsInStock) as 'In Stock',
  FROM ...
  GROUP BY InventoryItem.ItemName, InventoryItemDescription.ItemDescription

您可以使用SELECT DISTINCT,这与GROUP BY相同。

或者您可以利用窗口函数来计算平均值/总计,同时仍然保留每个描述或仓库值。

WITH CTE AS 
(
  SELECT
      InventoryItem.ItemName as 'Part Number',
      InventoryItemDescription.ItemDescription as 'Description',
      InventoryStockTotal.WarehouseCode AS 'Warehouse',
      InventoryItem.Status,
      SUM(InventoryStockTotal.UnitsInStock) OVER (PARTITION BY InventoryItem.ItemName) as 'In Stock',
      ROW_NUMBER() OVER() AS RowNumber
      FROM 
      ....
      // NO GROUP BY
)
SELECT colums
FROM CTE
WHERE RowNumber = 1

关于sql - 如何聚合描述列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36760088/

相关文章:

sql - SSIS - 将文件动态移动到具有匹配子字符串名称的文件夹

sql-server - 如何在动态查询中连接 uniqueidentifier

R 通过两组变量求和

date - 在精确范围内查询最大日期并获取结果中的选定字段

MySQL - 尝试插入字符串/数字时出现语法错误

sql - 在没有聚合函数的情况下进行分区,避免分组依据

sql - 如何从 SQL Server 2005 中的表中删除锁定?

sql - 舍入并显示2个小数位?

python - 使用 apply、transform、agg - Python Pandas 时如何引用 groupby 索引?

sql - 如何在 Postgres 中创建等效于 SQL Server 的标识列