用于定价分析的 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】:这可以通过查找与LocaProdname
、ProductGroup
和State
关联的 MAX/MIN 值来完成,然后加入所有匹配的表。见下文,或在http://sqlfiddle.com/#!3/4d6bd/2查看小提琴
注意:我已经添加了HAVING COUNT(*) > 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 查询的主要内容,如果未能解决你的问题,请参考以下文章