【问题标题】:SQL query for Pricing analysis用于定价分析的 SQL 查询
【发布时间】:2014-11-09 04:04:50
【问题描述】:

在 YearMonth 列上查找最小和最大定价状态时面临的问题,

下面是我的表格数据

   YearMonth    STATE   ProductGroup    LocaProdname    Price
    201407      MH      AIRTEL          AIRTEL-3G       10,000
    201208      GJ      IDEA            IDEA-3G         1,200
    201406      WB      AIRCEL          AIRCEL PERPAID  5,866
    201407      DL      TATA DOCOMA     TATA LANDLINE   8,955
    201207      KAR     VODAFONE        VODAFONE-3G     7,899
    201312      MH      AIRTEL          AIRTEL-3G       15,000
    201408      GJ      IDEA            IDEA-3G         25,000

我需要以下输出:

YearMonth   STATE   ProductGroup    LocaProdname    Price   Indictor-YEAR
201407      MH      AIRTEL          AIRTEL-3G       10,000  MAX
201312      MH      AIRTEL          AIRTEL-3G       15,000  MIN
201408      GJ      IDEA            IDEA-3G         25,000  MAX
201208      GJ      IDEA            IDEA-3G         1,200   MIN

我需要 Max yearmonth 和 min Year 值。

【问题讨论】:

标签: sql sql-server-2008 aggregate-functions greatest-n-per-group


【解决方案1】:

请使用带有分区 BY 的 Row_number 并根据需要删除不需要的代码,

SELECT yearmonth,state,productgroup,locaprodname,price,operation
    FROM   (
    SELECT * FROM   (SELECT p.yearmonth,p.state,p.productgroup,p.locaprodname,p.price,'MAX' AS Operation,
                           Row_number() OVER( partition BY p.productgroup, p.locaprodname
                               ORDER BY p.price DESC) AS Row
                    FROM   pricingtest p) AS Maxx
            WHERE  Maxx.row = 1

    UNION ALL

    SELECT * FROM   (SELECT p.yearmonth,p.state,p.productgroup,p.locaprodname,p.price,'MIN' AS Operation,
                           Row_number() OVER( partition BY p.productgroup, p.locaprodname
                               ORDER BY p.price ASC) AS Row
                    FROM   pricingtest p) AS Minn
            WHERE  Minn.row = 1

    ) AS whole
    ORDER  BY yearmonth,productgroup  

【讨论】:

    【解决方案2】:

    一旦您获得最后一条和第一条记录,您就可以 UNION 结果:

    SELECT t.*, 'MIN' AS Indicator
    FROM 
      myTable t LEFT JOIN 
      myTable t2 ON t.YearMonth = t2.YearMonth AND t2.price < t.price
    WHERE t2.YearMonth IS NULL
    UNION
    SELECT t.*, 'MAX' AS Indicator
    FROM 
      myTable t LEFT JOIN 
      myTable t2 ON t.YearMonth = t2.YearMonth AND t2.price > t.price
    WHERE t2.YearMonth IS NULL
    

    如果您有多个相同最高价格的记录,上述查询将返回所有记录。此外,如果您在一个月内只有一条记录,则会返回 MIN 和 MAX 的两倍。

    【讨论】:

      【解决方案3】:

      这可以通过查找与LocaProdnameProductGroupState 关联的 MAX/MIN 值来完成,然后加入所有匹配的表。见下文,或在http://sqlfiddle.com/#!3/4d6bd/2查看小提琴

      注意:我已经添加了HAVING COUNT(*) &gt; 1,因为您似乎只想要改变价格的那些。 (即有超过 1 个条目)

      SELECT p.YearMonth
          ,p.State
          ,p.ProductGroup
          ,p.LocaProdname
          ,p.Price
          ,CASE 
              WHEN p.Price = a.MaxPrice
                  THEN 'MAX'
              WHEN p.Price = a.MinPrice
                  THEN 'MIN'
              END AS [Indicator-YEAR]
      FROM PricingTest p
      INNER JOIN (
          SELECT LocaProdname
              ,ProductGroup
              ,State
              ,MAX(Price) AS MaxPrice
              ,MIN(Price) AS MinPrice
          FROM pricingTest
          GROUP BY LocaProdname
              ,ProductGroup
              ,State
          HAVING COUNT(*) > 1
          ) a ON a.LocaProdname = p.LocaProdname
          AND a.ProductGroup = p.ProductGroup
          AND a.State= p.State
          AND (
              a.MaxPrice = p.Price
              OR a.MinPrice = p.Price
              )
      ORDER BY LocaProdname
      

      编辑:或者我只是注意到这是用户可能正在寻找的最大/最小YearMonth,如果是这种情况,请查看http://sqlfiddle.com/#!3/4d6bd/4 它基本上只是将所有对Price 的引用替换为YearMonth

      【讨论】:

      • 我已经编辑为 YearMonth,但我需要为单个产品创建两条记录,即包含所有值的最小 YearMonth 和 Max YearMonth,现在它显示了一个产品的所有记录。
      • 你检查过 sqlfiddle 吗?它确实为每个产品显示 2 行。
      【解决方案4】:

      如果我理解正确,您可以使用row_number()

      select YearMonth, STATE, ProductGroup, LocaProdname, Price,
             (case when seqnum_asc = 1 then 'MIN' else 'MAX' end) as Indicator
      from (select d.*,
                   row_number() over (partition by state, productgroup, localprodname
                                      order by price asc) as seqnum_asc,
                   row_number() over (partition by state, productgroup, localprodname
                                      order by pricedesc) as seqnum_desc
            from data
           ) d
      where seqnum_asc = 1 or seqnum_desc = 1;
      

      编辑:

      这是你想要的吗?

      select YearMonth, STATE, ProductGroup, LocaProdname, Price,
             (case when seqnum_asc = 1 then 'MIN' else 'MAX' end) as Indicator
      from (select d.*,
                   row_number() over (partition by YearMonth
                                      order by price asc) as seqnum_asc,
                   row_number() over (partition by YearMOnth
                                      order by pricedesc) as seqnum_desc
            from data
           ) d
      where seqnum_asc = 1 or seqnum_desc = 1;
      

      【讨论】:

      • 没有得到用户需要的东西,我需要一个输出,用户可以看到 YearMonth 的最大值和相应行的价格。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-04
      • 1970-01-01
      相关资源
      最近更新 更多