从仅较低的表中选择下部和上部

时间:2013-11-17 16:08:27

标签: mysql sql join

如何将带有family,name和'lowerbound'数的规范化表转换为具有族,名,下限和上限的结果集,其中上限定义为min(lowerbound of family) > current lowerbound,如果没有这样的数字存在,使用提供的号码

例如,如果这是架构和数据:

create table records(
  family varchar(10),
  name varchar(10),
  lowbound int(4)
  );

insert into records
values 
('letters', 'a',1),('letters', 'b',3),('letters', 'c',3),('letters', 'd',3),
('letters', 'e',7),('letters', 'f',7),('numbers', '12',1), ('numbers', '15',1), ('numbers', '18',4);

并且提供的数字是9,那么结果集应该是:

|  FAMILY | NAME | LOWER | UPPER |
|---------|------|-------|-------|
| letters |    a |     1 |     3 |
| letters |    b |     3 |     7 |
| letters |    c |     3 |     7 |
| letters |    d |     3 |     7 |
| letters |    e |     7 |     9 |
| letters |    f |     7 |     9 |
| numbers |   12 |     1 |     4 |
| numbers |   15 |     1 |     4 |
| numbers |   18 |     4 |     9 |

2 个答案:

答案 0 :(得分:2)

试试这个:

SELECT r1.family, r1.name, r1.lowbound lower, coalesce(min(r2.lowbound), 9) upper
FROM records r1
LEFT JOIN records r2 ON r1.family = r2.family AND r1.lowbound < r2.lowbound
GROUP BY r1.family, r1.name, r1.lowbound

小提琴here

答案 1 :(得分:1)

我认为最简单的表达方式是使用select子句中的相关子查询:

select r.*,
       coalesce((select r2.lowbound
                 from records r2
                 where r2.family = r.family and
                       r2.lowbound > r.lowbound
                 order by r2.lowbound
                 limit 1
                ), 9) as highbound
from records r;

coalesce()处理没有值的情况。在这种情况下,您的替换值为9

Here是SQL小提琴。