【问题标题】:SQL - Problem with SQL Query ; group by and joinSQL - SQL 查询问题;分组并加入
【发布时间】:2009-06-09 15:45:49
【问题描述】:

假设我有一个名为 [ProductPriceHistory] ​​的表,如下所示:

HistoryID..ProductCode..EffectDate..Price..IsActive...ProductName 1----------11------------1 Jan 09--------100--------true--------AAA 2---------11------------1 2 月 9 日--------150--------真实--------AAA 3----------11-----------1 Mar 09--------200--------假-----AAA 4----------22------------1 Jan 09--------150--------true-----BBB 5----------22-----------1 2 月 9 日-------200-------真--------BBB 6------------22------------1先生09--------250--------真------- AAA

我如何才能找到所有有效产品在最近日期的最终状态?

也就是说,我的查询会找到该行:

6---------22------------1先生09--------250--------真---- ---AAA

【问题讨论】:

    标签: sql grouping


    【解决方案1】:
    select * from ProductPriceHistory p1
    where EffectDate = 
    (select max(EffectDate) from ProductPriceHistory p2
    where p1.ProductCode = p2.ProductCode and p2.EffectDate<=getdate())
    

    【讨论】:

    • 您忘记了“IsActive=true”吗?
    • @jmsa - 如果所有引用的列(生效日期)都传递给聚合函数(它是),则不需要分组。这是此类问题的典型解决方案,但请注意,如果您没有 EffectDate 的唯一约束,则会输出重复的行。
    【解决方案2】:

    获取给定产品代码的价值使用:

    DECLARE @ProcuctCode  int
    SET @ProductCode=11
    
    SELECT
        h.* 
        FROM ProductPriceHistory h
            INNER JOIN (SELECT
                            ProductCode
                                ,MAX(EffectDate) AS MaxEffectDate
                            FROM ProductPriceHistory
                            WHERE ProductCode=@ProductCode
                                AND IsActive='true'
                            GROUP BY ProductCode
                       ) dt ON h.ProductCode=dt.ProductCode AND h.EffectDate=dt.MaxEffectDate
        WHERE h.ProductCode =@ProductCode
    

    查找所有产品使用:

    SELECT
        h.* 
        FROM ProductPriceHistory h
            INNER JOIN (SELECT
                            ProductCode
                                ,MAX(EffectDate) AS MaxEffectDate
                            FROM ProductPriceHistory
                            WHERE IsActive='true'
                            GROUP BY ProductCode
                       ) dt ON h.ProductCode=dt.ProductCode AND h.EffectDate=dt.MaxEffectDate
         ORDER BY h.ProductCode
    

    【讨论】:

    • 看起来不错,但您需要在某处放置一个 h.IsActive='true'。 +1
    • @wcm,派生表包含 IsActive='true',然后将连接到正确的行,因此无需在其他任何地方执行...
    • @KM,如果您假设 ProductCode 和 EffectiveDate 是唯一的,那么您是对的。这可能就是 JMSA 的意思,所以我承认这一点。
    • @wcm,这个问题没什么好说的,我只需要做出假设。如果不是这种情况,OP 可以轻松地对其进行修改以满足他们的需求。
    【解决方案3】:

    你没有完全指定——也许@tekBlues'查询是你想要的,或者也许:

    SELECT * FROM ProductPriceHistory t1
    WHERE t1.EffectDate =
      (SELECT MAX(t2.EffectDate)
       FROM ProductPriceHistory t2
       WHERE t2.IsActive=true)
      AND t1.IsActive=true
    

    【讨论】:

      【解决方案4】:

      假设 ProductCode 和 EffectDate 唯一标识一行,你可以这样做:

      SELECT *
        FROM productpricehistory
           , (SELECT productcode
                   , MAX(effectdate) effectdate
                FROM productpricehistory
               GROUP BY productcode) maxhistory
       WHERE productpricehistory.productcode = maxhistory.productcode
         AND productpricehistory.effectdate = maxhistory.effectdate
         AND IsActive = TRUE;
      

      如果 ProductCode 和 EffectDate 不能唯一标识一行,那么您可能希望使用 HistoryId 而不是 EffectDate,如果我们可以假设 HistoryId 是唯一的并且增加 HistoryId 也意味着增加 EffectDate。

      编辑:我意识到我对待 active 的方式与你不同 - 我假设 IsActive 仅适用于特定的 EffectDate,但我看到你通过将其“IsActive”设置为 false 来停用整个产品。我相应地进行了更新,假设您随后可以通过使用 IsActive = true 创建一个新行来激活产品。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-12-05
        • 1970-01-01
        • 2016-04-27
        • 1970-01-01
        • 1970-01-01
        • 2018-11-06
        • 2011-09-08
        相关资源
        最近更新 更多