我有一张包含类别,日期和费率的表格。每个类别对于不同的日期可以有不同的费率,一个类别在给定日期只能有一个费率。
Id CatId Date Rate
------ ------ ------------ ---------
000001 12 2009-07-07 1
000002 12 2009-07-08 1
000003 12 2009-07-09 1
000004 12 2009-07-10 2
000005 12 2009-07-15 1
000006 12 2009-07-16 1
000007 13 2009-07-08 1
000008 13 2009-07-09 1
000009 14 2009-07-07 2
000010 14 2009-07-08 1
000010 14 2009-07-10 1
独特指数(catid,Date,Rate) 我希望每个类别对所有连续日期范围进行分组,并仅保留范围的开头和结尾。 对于前面的示例,我们将:
CatId Begin End Rate
------ ------------ ------------ ---------
12 2009-07-07 2009-07-09 1
12 2009-07-10 2009-07-10 2
12 2009-07-15 2009-07-16 1
13 2009-07-08 2009-07-09 1
14 2009-07-07 2009-07-07 2
14 2009-07-08 2009-07-08 1
14 2009-07-10 2009-07-10 1
我在the forum中找到了一个类似的解决方案,它没有完全给出结果
WITH q AS
(
SELECT *,
ROW_NUMBER() OVER (PARTITION BY CatId, Rate ORDER BY [Date]) AS rnd,
ROW_NUMBER() OVER (PARTITION BY CatId ORDER BY [Date]) AS rn
FROM my_table
)
SELECT CatId AS catidd, MIN([Date]) as beginn, MAX([Date])as endd, Rate
FROM q
GROUP BY CatId, rnd - rn, Rate
SEE SQL FIDDLE 我怎么能在mysql中做同样的事情? 请帮忙!
答案 0 :(得分:6)
MySQL不支持分析函数,但您可以使用user-defined variables:
模拟此类行为SELECT CatID, Begin, MAX(Date) AS End, Rate
FROM (
SELECT my_table.*,
@f:=CONVERT(
IF(@c<=>CatId AND @r<=>Rate AND DATEDIFF(Date, @d)=1, @f, Date), DATE
) AS Begin,
@c:=CatId, @d:=Date, @r:=Rate
FROM my_table JOIN (SELECT @c:=NULL) AS init
ORDER BY CatId, Rate, Date
) AS t
GROUP BY CatID, Begin, Rate
在sqlfiddle上查看。
答案 1 :(得分:3)
SELECT catid,min(ddate),max(ddate),rate
FROM (
SELECT
Catid,
Ddate,
rate,
@rn := CASE WHEN (@prev <> rate
or DATEDIFF(ddate, @prev_date)>1) THEN @rn+1 ELSE @rn END AS rn,
@prev := rate,
@prev_id := catid ,
@prev_date :=ddate
FROM (
SELECT CatID,Ddate,rate
FROM rankdate
ORDER BY CatID, Ddate ) AS a ,
(SELECT @prev := -1, @rn := 0, @prev_id:=0 ,@prev_date:=-1) AS vars
) T1 group by catid,rn
注意:Mysql Workspace中不需要行(SELECT @prev:= -1,@ rn:= 0,@ prev_id:= 0,@ prev_date:= - 1)AS vars ,但它在PHP mysql_query函数中。
答案 2 :(得分:0)
我知道我迟到了,仍然发布一个对我有用的解决方案。 有同样的问题,这就是我得到它的方式
使用变量
找到了一个很好的解决方案SELECT MIN(id) AS id, MIN(date) AS date, MIN(state) AS state, COUNT(*) cnt
FROM (
SELECT @r := @r + (@state != state OR @state IS NULL) AS gn,
@state := state AS sn,
s.id, s.date, s.state
FROM (
SELECT @r := 0,
@state := NULL
) vars,
t_range s
ORDER BY
date, state
) q
GROUP BY gn
更多详情请见:https://explainextended.com/2009/07/24/mysql-grouping-continuous-ranges/