ORDER BY 在子句 "IN()" 中指定的值,但在泛型 SQL 和 Informix 中
ORDER BY Values especified in clausule "IN()" BUT in Generics SQL and Informix
我希望不会重复另一个问题...我找不到解决方案。所有的解决方案都是针对 MySql.
我想按子句 IN 中的值对查询结果进行排序。但是在 Internet 和 Whosebug 中,只需找到 "MySql" 的解决方案,如下所示:
Order by FIELD in MYSQL
Ordering by specific field value first
MySQL ORDER BY FIELD with %
使用子句 FIELD 或 FIELD_IN_SET。我可以使用类似的东西吗?
谢谢!!
我只是尝试...但它不起作用。这是我的查询。
select * from (
select 4 as dato1 from systables where tabid = 1 union
select 2 as dato1 from systables where tabid = 1 union
select 1 as dato1 from systables where tabid = 1 union
select 3 as dato1 from systables where tabid = 1
)
where dato1 in (4,2,1,3)
order by instr('4,2,1,3', dato1)
这是查询显示:
dato1
1
2
4
3
我不明白...
一种适用于许多数据库的方法是这样的:
where x in ('a', 'b', 'c')
order by instr('a,b,c', x)
当然,分隔符会出问题,所以这样比较安全:
where x in ('a', 'b', 'c')
order by instr(',a,b,c,', ',' || x || ',', )
对于 informix 12.10(开发版),INSTR() 似乎无法将函数参数正确转换为字符类型。
我对 VARCHAR 进行了显式转换,INSTR() 函数开始为 return 正确的值。
select
dato1
from (
select 4 as dato1 from systables where tabid = 1 union
select 2 as dato1 from systables where tabid = 1 union
select 1 as dato1 from systables where tabid = 1 union
select 3 as dato1 from systables where tabid = 1
)
where dato1 in (4,2,1,3)
order by instr('4,2,1,3', CAST(dato1 AS VARCHAR(255)))
Returns:
dato1
4
2
1
3
编辑:
阐明INSTR()函数的使用:
select
dato1
, instr('4213', CAST(dato1 AS VARCHAR(255))) AS position
from (
select 4 as dato1 from systables where tabid = 1 union
select 2 as dato1 from systables where tabid = 1 union
select 1 as dato1 from systables where tabid = 1 union
select 3 as dato1 from systables where tabid = 1
)
where dato1 in (4,2,1,3)
order by instr('4213', CAST(dato1 AS VARCHAR(255)))
Returns:
dato1 position
4 1
2 2
1 3
3 4
话虽如此,Ricardo 的 DECODE() 建议似乎是更好的选择。
本回答仅对@luís-marques and @gordon-linoff已经给出的解决方案进行说明。
自 11.70 版以来,informix 具有 INSTR 函数,该函数接受一个字符串并查找子字符串,并且 returns 该字符串中该子字符串开始出现的字符位置(IBM 文档说它结束了,但它是一个文档错误)。
您使用的解决方案是:
SELECT
dato1
FROM (
SELECT 4 AS dato1 FROM systables WHERE tabid = 1 UNION
SELECT 2 AS dato1 FROM systables WHERE tabid = 1 UNION
SELECT 1 AS dato1 FROM systables WHERE tabid = 1 UNION
SELECT 3 AS dato1 FROM systables WHERE tabid = 1
)
WHERE dato1 IN (4,2,1,3)
ORDER BY INSTR('4,2,1,3', CAST(dato1 AS VARCHAR(255)));
要了解正在发生的事情,您可以:
SELECT
dato1,
INSTR('4,2,1,3', CAST(dato1 AS VARCHAR(255))) AS instr_res
FROM (
SELECT 4 AS dato1 FROM systables WHERE tabid = 1 UNION
SELECT 2 AS dato1 FROM systables WHERE tabid = 1 UNION
SELECT 1 AS dato1 FROM systables WHERE tabid = 1 UNION
SELECT 3 AS dato1 FROM systables WHERE tabid = 1
)
WHERE dato1 IN (4,2,1,3)
ORDER BY 2;
那将输出:
dato1 instr_res
4 1
2 3
1 5
3 7
但请记住,您在使用分隔符时可能会遇到问题,已用 @gordon-linoff 标记。
例如:
SELECT
dato1,
INSTR('444,44,4', CAST(dato1 AS VARCHAR(255))) AS instr_res
FROM (
SELECT 4 AS dato1 FROM systables WHERE tabid = 1 UNION
SELECT 44 AS dato1 FROM systables WHERE tabid = 1 UNION
SELECT 444 AS dato1 FROM systables WHERE tabid = 1
)
WHERE dato1 IN (444,44,4)
ORDER BY 2;
dato1 instr_res
4 1
44 1
444 1
为了得到这个排序总是分隔你想要的值的开始和结束,对于这种情况它将是:
SELECT
dato1,
INSTR(',444,44,4,', ','||CAST(dato1 AS VARCHAR(255))||',') AS instr_res
FROM (
SELECT 4 AS dato1 FROM systables WHERE tabid = 1 UNION
SELECT 44 AS dato1 FROM systables WHERE tabid = 1 UNION
SELECT 444 AS dato1 FROM systables WHERE tabid = 1
)
WHERE dato1 IN (444,44,4)
ORDER BY 2;
dato1 instr_res
444 1
44 5
4 8
另一种方法是使用 CHARINDEX 函数,自 11.70 起也可用。请注意参数的顺序是相反的;首先传递要查找的子字符串,然后传递源字符串。使用 CHARINDEX
的好处是不需要强制转换。
SELECT
dato1,
CHARINDEX(','||dato1||',', ',444,4,44,') AS charindex_res
FROM (
SELECT 4 AS dato1 FROM systables WHERE tabid = 1 UNION
SELECT 44 AS dato1 FROM systables WHERE tabid = 1 UNION
SELECT 444 AS dato1 FROM systables WHERE tabid = 1
)
WHERE dato1 IN (444,4,44)
ORDER BY 2;
dato1 charindex_res
444 1
4 5
44 7
当使用没有 INSTR
的旧版本 Informix 时,可以使用 DECODE:
SELECT
dato1
FROM (
SELECT 4 AS dato1 FROM systables WHERE tabid = 1 UNION
SELECT 2 AS dato1 FROM systables WHERE tabid = 1 UNION
SELECT 1 AS dato1 FROM systables WHERE tabid = 1 UNION
SELECT 3 AS dato1 FROM systables WHERE tabid = 1
)
WHERE dato1 IN (4,2,1,3)
ORDER BY DECODE(
dato1,
4, 1,
2, 2,
1, 3,
3, 4
);
我希望不会重复另一个问题...我找不到解决方案。所有的解决方案都是针对 MySql.
我想按子句 IN 中的值对查询结果进行排序。但是在 Internet 和 Whosebug 中,只需找到 "MySql" 的解决方案,如下所示:
Order by FIELD in MYSQL
Ordering by specific field value first
MySQL ORDER BY FIELD with %
使用子句 FIELD 或 FIELD_IN_SET。我可以使用类似的东西吗?
谢谢!!
我只是尝试...但它不起作用。这是我的查询。
select * from (
select 4 as dato1 from systables where tabid = 1 union
select 2 as dato1 from systables where tabid = 1 union
select 1 as dato1 from systables where tabid = 1 union
select 3 as dato1 from systables where tabid = 1
)
where dato1 in (4,2,1,3)
order by instr('4,2,1,3', dato1)
这是查询显示:
dato1
1
2
4
3
我不明白...
一种适用于许多数据库的方法是这样的:
where x in ('a', 'b', 'c')
order by instr('a,b,c', x)
当然,分隔符会出问题,所以这样比较安全:
where x in ('a', 'b', 'c')
order by instr(',a,b,c,', ',' || x || ',', )
对于 informix 12.10(开发版),INSTR() 似乎无法将函数参数正确转换为字符类型。
我对 VARCHAR 进行了显式转换,INSTR() 函数开始为 return 正确的值。
select
dato1
from (
select 4 as dato1 from systables where tabid = 1 union
select 2 as dato1 from systables where tabid = 1 union
select 1 as dato1 from systables where tabid = 1 union
select 3 as dato1 from systables where tabid = 1
)
where dato1 in (4,2,1,3)
order by instr('4,2,1,3', CAST(dato1 AS VARCHAR(255)))
Returns:
dato1
4
2
1
3
编辑:
阐明INSTR()函数的使用:
select
dato1
, instr('4213', CAST(dato1 AS VARCHAR(255))) AS position
from (
select 4 as dato1 from systables where tabid = 1 union
select 2 as dato1 from systables where tabid = 1 union
select 1 as dato1 from systables where tabid = 1 union
select 3 as dato1 from systables where tabid = 1
)
where dato1 in (4,2,1,3)
order by instr('4213', CAST(dato1 AS VARCHAR(255)))
Returns:
dato1 position
4 1
2 2
1 3
3 4
话虽如此,Ricardo 的 DECODE() 建议似乎是更好的选择。
本回答仅对@luís-marques and @gordon-linoff已经给出的解决方案进行说明。
自 11.70 版以来,informix 具有 INSTR 函数,该函数接受一个字符串并查找子字符串,并且 returns 该字符串中该子字符串开始出现的字符位置(IBM 文档说它结束了,但它是一个文档错误)。
您使用的解决方案是:
SELECT
dato1
FROM (
SELECT 4 AS dato1 FROM systables WHERE tabid = 1 UNION
SELECT 2 AS dato1 FROM systables WHERE tabid = 1 UNION
SELECT 1 AS dato1 FROM systables WHERE tabid = 1 UNION
SELECT 3 AS dato1 FROM systables WHERE tabid = 1
)
WHERE dato1 IN (4,2,1,3)
ORDER BY INSTR('4,2,1,3', CAST(dato1 AS VARCHAR(255)));
要了解正在发生的事情,您可以:
SELECT
dato1,
INSTR('4,2,1,3', CAST(dato1 AS VARCHAR(255))) AS instr_res
FROM (
SELECT 4 AS dato1 FROM systables WHERE tabid = 1 UNION
SELECT 2 AS dato1 FROM systables WHERE tabid = 1 UNION
SELECT 1 AS dato1 FROM systables WHERE tabid = 1 UNION
SELECT 3 AS dato1 FROM systables WHERE tabid = 1
)
WHERE dato1 IN (4,2,1,3)
ORDER BY 2;
那将输出:
dato1 instr_res
4 1
2 3
1 5
3 7
但请记住,您在使用分隔符时可能会遇到问题,已用 @gordon-linoff 标记。
例如:
SELECT
dato1,
INSTR('444,44,4', CAST(dato1 AS VARCHAR(255))) AS instr_res
FROM (
SELECT 4 AS dato1 FROM systables WHERE tabid = 1 UNION
SELECT 44 AS dato1 FROM systables WHERE tabid = 1 UNION
SELECT 444 AS dato1 FROM systables WHERE tabid = 1
)
WHERE dato1 IN (444,44,4)
ORDER BY 2;
dato1 instr_res
4 1
44 1
444 1
为了得到这个排序总是分隔你想要的值的开始和结束,对于这种情况它将是:
SELECT
dato1,
INSTR(',444,44,4,', ','||CAST(dato1 AS VARCHAR(255))||',') AS instr_res
FROM (
SELECT 4 AS dato1 FROM systables WHERE tabid = 1 UNION
SELECT 44 AS dato1 FROM systables WHERE tabid = 1 UNION
SELECT 444 AS dato1 FROM systables WHERE tabid = 1
)
WHERE dato1 IN (444,44,4)
ORDER BY 2;
dato1 instr_res
444 1
44 5
4 8
另一种方法是使用 CHARINDEX 函数,自 11.70 起也可用。请注意参数的顺序是相反的;首先传递要查找的子字符串,然后传递源字符串。使用 CHARINDEX
的好处是不需要强制转换。
SELECT
dato1,
CHARINDEX(','||dato1||',', ',444,4,44,') AS charindex_res
FROM (
SELECT 4 AS dato1 FROM systables WHERE tabid = 1 UNION
SELECT 44 AS dato1 FROM systables WHERE tabid = 1 UNION
SELECT 444 AS dato1 FROM systables WHERE tabid = 1
)
WHERE dato1 IN (444,4,44)
ORDER BY 2;
dato1 charindex_res
444 1
4 5
44 7
当使用没有 INSTR
的旧版本 Informix 时,可以使用 DECODE:
SELECT
dato1
FROM (
SELECT 4 AS dato1 FROM systables WHERE tabid = 1 UNION
SELECT 2 AS dato1 FROM systables WHERE tabid = 1 UNION
SELECT 1 AS dato1 FROM systables WHERE tabid = 1 UNION
SELECT 3 AS dato1 FROM systables WHERE tabid = 1
)
WHERE dato1 IN (4,2,1,3)
ORDER BY DECODE(
dato1,
4, 1,
2, 2,
1, 3,
3, 4
);