2

我有一个SQL query我想根据搜索参数获取颜色的名称。(数据库:Oracle10,前端:Java)

表 (table1)

ID  COLORNAME
--- --------------------
1   Blue
2   Light Blue
3   Dark Blue
4   Dark Red
5   Light Red
6   Red

以下是我获取包含Red单词的颜色列表的查询(搜索参数为Red

select * from table1
where colorname LIKE '%Red%'

输出:

ID  COLORNAME
--- --------------------
4   Dark Red
5   Light Red
6   Red

上面的输出是正确的,但我希望ColorNameRedmust 开头,然后是包含单词的颜色Red

期待:

ID  COLORNAME
--- --------------------
6   Red
4   Dark Red
5   Light Red

那么如何在查询中实现这一点?

4

4 回答 4

2

取决于您如何决定应该首先使用红色。在您的具体情况下

select * 
from table1
where colorname LIKE '%Red%'
order by nullif(colorname , 'Red') nulls first
于 2013-06-15T08:32:45.897 回答
1
(select * from table1 where colorname = 'red')
union
(select * from table1 where colorname like '%red%' and colorname != 'red')

编辑:考虑到这一点,它实际上不是一种保证的排序 - 但可能在所有情况下都会如此。

要保证此方法,您必须这样做:

(select <cols>, colorname, 1 as i from table1 where colorname = 'red')
union
(select <cols>, colorname, 2 as i from table1 where colorname like '%red%' and colorname != 'red')
order by i, colorname

或者你可以使用@haki 的建议

再次编辑,想想在某些 dbms 中实际上有一种更简单的方法:

select * from table1
where colorname like '%red%'
order by (colorname = 'red') desc, colorname
于 2013-06-15T08:30:18.963 回答
1

我建议在您的数据模型中添加“家庭”和“职位”:

ID  FAMILY POS COLORNAME  
--- --------------------  
4   Red    20  Dark Red  
5   Red    30  Light Red  
6   Red    10  Red  

然后就可以了order by family, pos, colorname。定义任何其他排序模式都很灵活。

为了加快速度,您可以在这些列上放置一个索引:如果您使用 '%red%',它可能始终是全表扫描。

于 2013-06-15T08:46:53.393 回答
1

将此扩展到更通用的标准,我认为完全匹配将是具有最小长度的匹配。

所以你可以:

with required_rows as (
  select t.*
         length(colorname)              length_colorname    ,
         min(length(colorname)) over () min_length_colorname
  from   table1
  where  colorname like '%Red%')
select   id,
         colorname
from     required_rows
order by case length_colorname
           when min_length_colorname then 0
           else 1
         end,
         colorname

如果您不需要对其他行进行排序,那么您当然可以按长度(颜色名称)排序。

于 2013-06-15T09:33:18.070 回答