EXPERT RESPONSE
This is the classic "runs" problem.
select category
, mark
, start
, case when start = end
then null
else end end as end
from (
select dt.category
, dt.mark
, min(dt.num) as start
, max(dt.num) as end
from (
select s1.category
, s1.mark
, s1.num
, s1.num -
( select count(*)
from goods as s2
where s2.category = s1.category
and s2.mark = s1.mark
and s2.num <= s1.num )
as diff_rank
from goods as s1
) as dt
group
by dt.category
, dt.mark
, dt.diff_rank
) as dt2
order
by category
, start
For the solution, I am indebted to Joe Celko's
SQL for Smarties, 3rd edition, page 556.
Please do not ask me to explain it. Instead, test it yourself,
by building up your query starting at the DT subquery.
Analyze the results carefully. The outermost query is merely
for cosmetic purposes.
Incidentally, this is the first time I can recall ever
writing ELSE END END AS END in SQL.
This may not work in every database system, so use
identifier delimiters as necessary.
|