带有2个范围的SQL引用表

时间:2013-03-26 11:17:58

标签: sql design-patterns search reference

我有一个带有两个数字列的参考表,用于定义一个范围,例如一个帐户和每个员工范围的员工,我得到一个公司规模:

employeeMin   employeeMax   Size
1             100           small
101           2000          medium
2001          10000         medium-large
10001         100000        large

......等等

我需要返回给定参数的大小,比如说110会返回'medium' 如你所见第二列总是=第一列+ 1

所以我想知道是否更好地在sql中使用两列实现它,或者我应该只使用employeeMax并且可能订购并返回第一条记录?我希望存在一种模式?也许自我加入或类似?我做了一些研究但却找不到......

3 个答案:

答案 0 :(得分:2)

这完全取决于你的目标,例如:

可维护性 - 如果您不经常阅读或使用任何类型的优化(例如,物化视图),请使用1列

employeeMax   Size
100           small
2000          medium
10000         medium-large
100000        large

select *
from accounts a
join (      
    select
        cs1.emploeeAbove,
        coalesce(min(cs2.emploeeAbove), 999999999) employeeMax,
        Size
    from company_sizes cs1
    left join company_sizes cs2
        on cs2.employeeAbove > cs1.employeeAbove
    group by cs1.employeeAbove, Size
) cs
    on a.emploees > cs.employeeAbove
    and a.employees <= cs.employeeMax

更快的加入 - 如果您有数百万条记录并且您没有弄清楚如何优化之前的方法,请使用2列设计

employeeAbove   employeeMax   Size
0               100           small
100             2000          medium
2000            10000         medium-large
10000           100000        large

select *
from accounts a
join company_sizes cs
    on a.emploees > cs.employeeAbove
    and a.employees <= cs.employeeMax

答案 1 :(得分:0)

我建议仅使用employeeMin列,然后移除employeeMax。这样,最大尺寸对于将来可能具有的“x大”尺寸是开放式的。

 SELECT Size FROM yourtable WHERE employeeMin <= 110 ORDER BY employeeMin DESC LIMIT 1

答案 2 :(得分:0)

我肯定会使用一列,无论是最小还是最大。除此之外,这可以确保您的范围之间没有任何差距。假设max,您的表格看起来像:

employeeMax   Size
100           small
2000          medium
10000         medium-large
100000        large

您获得实际范围的查询将类似于:

select 
     coalesce((select max(employeeMax) 
               from CompanySize b 
               where b.employeemax < a.employeemax),
              0) as employeeMin
     a.employeeMax, 
     a.size
from CompanySize

如果您的数据库支持分析功能,您可以稍微简化一下:

select 
     coalesce(lag(employeeMax) over (order by employeemax asc),
              0) as employeeMin
     a.employeeMax, 
     a.size
from CompanySize