我正在使用具有不同数据类型的UNION语句,并希望对它们进行排序。
SELECT * FROM
(SELECT name, 'P' as 'type', to_char(order_number) as order_type FROM abc
UNION ALL
SELECT name, 'T' as 'type', to_char(name) as order_type FROM def
)
ORDER BY
CASE type
WHEN 'P' THEN order_type
ELSE
order_type
END
到目前为止这是有效的。
现在表abc
中order_type的内容是整数,表def
中的内容是varchar。
这就是为什么结果的顺序是错误的。 (例如1000在11之前)
我尝试使用
ORDER BY
CASE type WHEN 'P' THEN CAST(order_type AS NUMBER)
ELSE order_type END
在订单部分,但我正在
INCONSISTENT DATATYPES
我做错了什么?
表格内容:
abc
:
name | order_number
'Example 1' | 10001
'Example 2' | 11
def
:
name | order_number
'Example 4' | 0
'Example 3' | 0
预期结果:
Example 2
Example 1
Example 3
Example 4
答案 0 :(得分:1)
您的列ORDER_TYPE是一个字符串,将作为一个字符串排序,因此11在2.之前。您希望将来自表ABC的字符串作为数字排序,并按字母顺序排列来自表DEF的字符串。
一种方法可能是:
ORDER BY CASE type WHEN 'P' THEN lpad(order_type,20,'0') ELSE order_type END
那个顺序依次是字符串排序,但是用零填充数字,这将按数字排序(因为你说它是整数数据 - 如果你有一些可能使它复杂化的分数;-)
答案 1 :(得分:1)
在顺序中使用常量'4'
或4
没有达到任何效果;不会转换为列位置。
无论原始数据类型是什么,联合都会将来自两个分支的数据呈现为相同类型(由第一个分支确定)。你有to_char(c)
这意味着order_type
是一个字符串; f
已经是一个字符串,但即使它是一个数字,它也会被隐式转换为匹配。
CASE type WHEN 'P' THEN CAST(order_type AS NUMBER)
ELSE order_type END
当你这样做时,order_type是一个字符串; then
将其转换为数字,else
不是,因此数据类型不同。
如果您想以数字方式订购,请将order_type
设为数字,然后按顺序排序:
SELECT * FROM
(SELECT a,b,'P' as "type", c as order_type FROM abc
UNION ALL
SELECT d,e,'T' as "type", to_number(f) as order_type FROM def
)
ORDER BY order_type;
或者如果您需要将结果集中的order_type
作为字符串,请在order-by子句中将其转换回来:
SELECT * FROM
(SELECT a,b,'P' as "type", to_char(c) as order_type FROM abc
UNION ALL
SELECT d,e,'T' as "type", f as order_type FROM def
)
ORDER BY to_number(order_type);
......但这似乎相当多余。
当然,这假设f
中的所有值实际上都是存储为字符串的有效数字(这是一个完全不同的主题)。如果它们不能全部被转换,那么无论哪种方式,你都会得到无效数字错误;然后你最好的选择可能是填充字符串结果@KimBergHansen建议,虽然他说非整数值可能会给出奇怪的结果,你需要选择一个适当大的长度。
根据您的问题编辑,您似乎希望首先按abc
排序order_num
值,然后按def
排序name
值。在这种情况下,使用多个元素:
SELECT * FROM
(SELECT name, 'P' as order_type, order_num FROM abc
UNION ALL
SELECT name,'T' as order_type, null as order_num FROM def
)
ORDER BY CASE WHEN order_type = 'P' THEN 1 ELSE 2 END,
order_num,
name;
NAME ORDER_TYPE ORDER_NUM
---------- ---------- ----------
Example 2 P 11
Example 1 P 10001
Example 3 T
Example 4 T
来自您的样本数据的
答案 2 :(得分:1)
重点是,在您的order by子句中,您正在混合数据类型
with t1(text) as (
select '1' from dual union all
select 'P' from dual union all
select '4' from dual
)
select * from t1
ORDER BY
CASE text
WHEN 'P' THEN CAST('4' AS NUMBER)
ELSE
'4'
END;
错误:ORA-00932: inconsistent datatypes: expected NUMBER got CHAR
这里,char与数字混合。要获得从案例返回的一致数据类型,您需要将else部分转换为数字,从案例的每个条件返回,就数据类型而言是一致的
with t1(text) as (
select '1' from dual union all
select 'P' from dual union all
select '4' from dual
)
select * from t1
ORDER BY
CASE text
WHEN 'P' THEN CAST('4' AS NUMBER)
ELSE
CAST('4' AS NUMBER) -- or just 4 without qoutes
END;
输出:
| TEXT |
|------|
| 1 |
| 4 |
| P |
答案 3 :(得分:1)
SQL> WITH DATA AS(
2 select ename, to_char(sal) sal from emp)
3 select ename ,sal from data
4 ORDER BY
5 to_number(sal)
6 /
ENAME SAL
---------- ----------------------------------
SMITH 800
JAMES 950
ADAMS 1100
WARD 1250
MARTIN 1250
MILLER 1300
TURNER 1500
ALLEN 1600
CLARK 2450
BLAKE 2850
JONES 2975
SCOTT 3000
FORD 3000
KING 5000
14 rows selected.