【问题标题】:Getting a DISTINCT value in a subquery在子查询中获取 DISTINCT 值
【发布时间】:2019-12-02 14:16:03
【问题描述】:

我最近一直在尝试将 First() 函数从 MS Access 转换为 T-SQL。现在 First() 在 T-SQL 中不存在,所以我不得不探索一些替代方案。我找到了似乎可以完成这项工作的 First_Value 函数。

但是,请使用下面的代码:

SELECT [Order Transactions Table].[Job Number],
   [Order Transactions Table].OutstandingBalance,
   [Order Transactions Table].[Accepted Quantity],
   MRPStockOut.MRPStockOutID,
   MRPStockOut.[Date],
   MRPStockOut.[Units],
   MRPHeader.MRPHeaderID,
   FIRST_VALUE(MRPSupplier.StockCode) OVER (PARTITION BY MRPSupplier.StockCode ORDER BY MRPSupplier.StockCode) AS FirstOfStockCode,
   --(SELECT TOP (1) MRPSupplier.StockCode ORDER BY [Order Transactions Table].[Job Number]) AS FirstOfStockCode,
   MRPHeader.MaterialDescription,
   MRPStockOut.StockQtyOut,
   MRPHeader.WeightPerUnit * MRPStockOut.StockQtyOut AS [Weight],
   LiveWIPStockAllocatedToJobsPrices.PurchPriceEach,
   LiveWIPStockAllocatedToJobsPrices.StockPriceEach,
   LiveWIPStockAllocatedToJobsPrices.PriceEach,
   (IIF(ISNULL(LiveWIPStockAllocatedToJobsPrices.PurchPriceEach,0) > 0,
    ISNULL(LiveWIPStockAllocatedToJobsPrices.PurchPriceEach,0),
    ISNULL(LiveWIPStockAllocatedToJobsPrices.StockPriceEach,0)) +0) * MRPStockOut.StockQtyOut AS TotalPrice

FROM [Order Transactions Table]
INNER JOIN MRPStockOut ON [Order Transactions Table].[Job Number] = MRPStockOut.JobNumber
INNER JOIN MRPHeader ON MRPStockOut.MRPHeaderID = MRPHeader.MRPHeaderID
INNER JOIN LiveWIPStockAllocatedToJobsPrices ON MRPHeader.MRPHeaderID = 
LiveWIPStockAllocatedToJobsPrices.MRPHeaderID
INNER JOIN MRPSupplier ON MRPHeader.MRPHeaderID = MRPSupplier.MRPHeaderID
GROUP BY
[Order Transactions Table].[Job Number],
[Order Transactions Table].OutstandingBalance,
[Order Transactions Table].[Accepted Quantity],
MRPStockOut.MRPStockOutID,
MRPStockOut.[Date],
MRPStockOut.[Units],
MRPHeader.MRPHeaderID,
MRPSupplier.StockCode,
MRPHeader.MaterialDescription, 
MRPStockOut.StockQtyOut,
MRPHeader.WeightPerUnit * MRPStockOut.StockQtyOut,
LiveWIPStockAllocatedToJobsPrices.PurchPriceEach,
LiveWIPStockAllocatedToJobsPrices.StockPriceEach,
LiveWIPStockAllocatedToJobsPrices.PriceEach,
(IIF(ISNULL(LiveWIPStockAllocatedToJobsPrices.PurchPriceEach,0) > 0,
ISNULL(LiveWIPStockAllocatedToJobsPrices.PurchPriceEach,0),
ISNULL(LiveWIPStockAllocatedToJobsPrices.StockPriceEach,0)) +0) * MRPStockOut.StockQtyOut
Having [Order Transactions Table].OutstandingBalance > 0

特别是在 MRPSupplier 中选择第一个值的行。 (First(MRPSupplier.StockCode) in Access)

FIRST_VALUE(MRPSupplier.StockCode) OVER (PARTITION BY MRPSupplier.StockCode ORDER BY MRPSupplier.StockCode) AS FirstOfStockCode

现在这个值返回了我所期望的值,但是,在相同的 [作业编号] 下,某些作业返回了 2 条记录而不是 1 条记录。这是因为其中一个重复作业返回 FirstOfStockCode = Null,而另一个具有预期值。

这是一个问题,因为这是一个子查询,我在上面的查询中有一个 SUM,这给了我一个不正确的结果,因为 TotalPrice 由于重复记录而被求和两次。我怎样才能得到它,以便我只收到来自该列的 Distinct 值?

编辑:

当前结果:

预期结果是上面唯一的第二条记录被选中,第一个 NULL 记录不应该在选择列表中。

编辑 2:

这是更多记录的另一个屏幕截图(546 行 - 这比我在 MS Access 中获得的多两个):

同样,这两个 Null 值记录不应该存在,因为它们是重复的 编辑3: 用户@Isaac 设法帮助我解决了这个问题。请参阅他的答案中的 cmets 线程。

【问题讨论】:

  • 样本数据和预期结果会有所帮助
  • @ShikharArora 我已经编辑了我得到的结果的屏幕截图以及我的期望。有什么想法吗?

标签: sql-server tsql ms-access group-by migration


【解决方案1】:

尝试替换此行...

FIRST_VALUE(MRPSupplier.StockCode) OVER (PARTITION BY MRPSupplier.StockCode ORDER BY MRPSupplier.StockCode) AS FirstOfStockCode,

有了这个……

FIRST_VALUE(MRPSupplier.StockCode) OVER (ORDER BY MRPSupplier.StockCode) AS FirstOfStockCode,

我相信 PARTITION BY 子句会导致返回额外的行。如果这会导致返回具有 NULL 值的行,请像这样添加 DESC ...

FIRST_VALUE(MRPSupplier.StockCode) OVER (ORDER BY MRPSupplier.StockCode DESC) AS FirstOfStockCode,

【讨论】:

  • 我试过了,但我仍然得到 2 条记录,只是现在我在 FirstOfStockCode 中都得到了 NULL 的记录,当我按照你所说的添加 DESC 时,我得到了两条记录,FirstOfStockCode 为 CZ121 12 ,使两条记录完全相同。我只需要返回一条记录。
  • 没有测试数据供我们测试,排错有点困难。尽管如此,在 GROUP BY 中存在 MRPSupplier.StockCode 似乎是个问题。尝试将其替换为 FirstOfStockCode 的完整行。这有意义吗?
  • 如果您得到两个相同的行,您可以在 SELECT 之后立即添加 DISTINCT,但这可能会掩盖问题而不是解决问题。
  • 如果 MRPSupplier.StockCode 的 NULL 值是唯一的问题,那么您可以添加一个 where 子句来排除它们。
  • 当然!我怎么会错过这么简单的事情?这已经成功了,我上面的查询现在计算正确。访问中的 First() 似乎会自动忽略 NULL 记录,但 First_Value 不会这样做。谢谢!
猜你喜欢
  • 1970-01-01
  • 2020-12-29
  • 1970-01-01
  • 1970-01-01
  • 2015-08-24
  • 2021-09-26
  • 2020-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多