用于定价分析的 SQL 查询

Posted

技术标签:

【中文标题】用于定价分析的 SQL 查询【英文标题】:SQL query for Pricing analysis 【发布时间】: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 值。

【问题讨论】:

Get values from first and last row per group的可能重复 在 SQL-Server 2008 中需要这个 ***.com/questions/tagged/… 【参考方案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 的最大值和相应行的价格。

以上是关于用于定价分析的 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

SQL 组行选择

大查询统一费率定价的复制,加载和导出操作的插槽利用率

使用 PHP PDO 在 SQL 中将多行传递给 UDF

SQL案例分析-地铁换乘线路查询.sql

流分析:源“子查询”只能用于使用“datediff”函数的时间谓词

如果我查询 Bigquery 视图,如何计算定价?