选择具有 MAX(Date) 但没有得到明显回报的记录

Posted

技术标签:

【中文标题】选择具有 MAX(Date) 但没有得到明显回报的记录【英文标题】:Select records with a MAX(Date) but don't get distinct return 【发布时间】:2013-07-29 08:14:53 【问题描述】:

我正在加入表格,我的代码如下所示:

SELECT P.*
FROM (
  SELECT ABC.StockCode
    ,ABC.Supplier
    ,ABC.Price
    ,MAX(ABC.OrigReceiptDate) ReceiptDate
  FROM (
    SELECT GRND.StockCode
      ,GRND.Supplier
      ,OrigReceiptDate
      ,(GRND.OrigGrnValue / GRND.QtyReceived) AS Price
    FROM [SysproCompanyR].[dbo].[GrnDetails] GRND
    WHERE QtyReceived > 0
    ) ABC
  GROUP BY ABC.StockCode
    ,ABC.Supplier
    ,ABC.Price
  ) P
WHERE P.StockCode IN (
    SELECT StockCode
    FROM [SysproCompanyR].[dbo].[InvMaster]
    )
ORDER BY P.StockCode
  ,P.Price

然而结果集是:

我的问题是我需要获取最新购买的股票代码及其价格...但是由于价格不同,我得到了重复的值,以帮助金发女郎>

【问题讨论】:

【参考方案1】:

试试这个:

WITH CTE
AS
(
    SELECT 
      ABC.StockCode, 
      ABC.Supplier, 
      ABC.Price,
      ABC.OrigReceiptDate AS ReceiptDate, 
      ROW_NUMBER() OVER(PARTITION BY ABC.Supplier
                        ORDER BY ABC.OrigReceiptDate DESC) AS RN 
    FROM
    (
       SELECT GRND.StockCode, GRND.Supplier,OrigReceiptDate, 
         (GRND.OrigGrnValue /GRND.QtyReceived) as Price
       FROM [SysproCompanyR].[dbo].[GrnDetails] GRND
       Where QtyReceived > 0
    ) AS ABC 
    INNER JOIN [SysproCompanyR].[dbo].[InvMaster] AS m 
            ON ABC.StockCode = m.StockCode
)
SELECT 
  StockCode, 
  Supplier, 
  Price,
  ReceiptDate
FROM CTE 
WHERE RN = 1;

这应该为您提供每个供应商最近购买的股票代码及其价格。

【讨论】:

您的 RowNumber 部分不会创建我见过的唯一行号,所以我有多个具有相同编号的 RN 列不知道这是否会发生...... @user1546143, 是的,这是因为 PARTITION BY ABC.Supplier 每个供应商都有其顺序取决于日期的排序,例如供应商 0203004 将具有从 1 到 n ,然后 0204260 将具有从 1 到 n 按日期降序排列,过滤器 WHERE RN = 1 将消除所有并保留第一个为最大日期。你试过了吗? 嗨,是的,我有,但是我的重复结果返回大约 3600 条记录,而你的只返回 154 条,但在我的返回列表中,我有你没有的股票代码... @user1546143 你可能想partition by 股票代码,而不是供应商。 @user1546143 - 能否请您发布一些示例数据和所需的输出,请不要轻易处理图片,这将非常有帮助。【参考方案2】:

在 WHERE 子句中使用 EXISTS 和相关子查询的更多选项

SELECT P.*
FROM (
      SELECT GRND.StockCode, GRND.Supplier, GRND.OrigReceiptDate, (GRND.OrigGrnValue / GRND.QtyReceived) AS Price
      FROM [SysproCompanyR].[dbo].[GrnDetails] AS GRND
      WHERE QtyReceived > 0      
      ) P
WHERE P.StockCode IN (
                      SELECT StockCode
                      FROM [SysproCompanyR].[dbo].[InvMaster]
                      )
  AND EXISTS(
             SELECT 1
             FROM [SysproCompanyR].[dbo].[GrnDetails] AS GRND2
             WHERE GRND.StockCode = GRND2.StockCode
               AND GRND.Supplier = GRND2.Supplier
             HAVING MAX(GRND2.OrigReceiptDate) = GRND.OrigReceiptDate
             )
ORDER BY P.StockCode, P.Price

【讨论】:

【参考方案3】:

我相信这种形式的查询更容易理解并且易于维护:

;WITH ABC AS (
  SELECT 
    GRND.StockCode,
    GRND.Supplier,
    OrigReceiptDate,
    Price = (GRND.OrigGrnValue / GRND.QtyReceived),
  FROM [SysproCompanyR].[dbo].[GrnDetails] GRND
  WHERE QtyReceived > 0
),
P AS (
  SELECT 
    ABC1.StockCode,
    lastOne.Supplier,
    lastOne.Price,
    ReceiptDate = lastOne.OrigReceiptDate
  FROM 
    (SELECT DISTINCT StockCode FROM ABC) ABC1
    CROSS APPLY(
      SELECT TOP 1
        Supplier,
        Price,
        OrigReceiptDate
      FROM ABC
      WHERE StockCode = ABC1.StockCode
      ORDER BY OrigReceiptDate DESC
    ) lastOne
)
SELECT *
FROM P
WHERE 
  StockCode IN (
    SELECT StockCode
    FROM [SysproCompanyR].[dbo].[InvMaster])
ORDER BY 
  StockCode,
  Price

【讨论】:

感谢@Mahmoud Gamal 的快速回复,这很有效,但由于某种原因,它遗漏了很多股票代码。我的结果重复返回大约 3600 条记录,而你的只返回 154 条记录,但在我的返回列表我有你没有的股票代码...@Ozren 它抱怨 olumn 'lastOne.Supplier' 在选择列表中无效,因为它既不包含在聚合函数或 GROUP BY 子句中。猜猜它需要按类分组中的那一列【参考方案4】:

我认为你可以这样做:

SELECT a.*
FROM( SELECT  StockCode,
              Supplier,
              OrigGrnValue/QtyReceived) AS Price,
              OrigReceiptDate AS ReceiptDate
      ROW_NUMBER() OVER (PARTITION BY StockCode, Supplier, OrigGrnValue/QtyReceived ORDER BY OrigReceiptDate DESC) as rown
      FROM GrnDetails
      WHERE QtyReceived > 0 ) a
WHERE a.rown = 1
AND a.StockCode EXISTS (SELECT StockCode
                        FROM [SysproCompanyR].[dbo].[InvMaster] m
                        WHERE m.StockCode = a.StockCode)
ORDER BY a.StockCode,
         a.Price

【讨论】:

以上是关于选择具有 MAX(Date) 但没有得到明显回报的记录的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server:仅选择具有 MAX(DATE) 的行

选择具有最大值的行,并结合WHERE。 MAX和CAST,在spark.sql中

如何在没有分组依据的情况下选择具有最大技能属性的 ID

如何选择具有最大值的行的所有列

HQL选择组内具有最大值的实体的ID

选择最新的行