此问题是我earlier query的延续。它仍然无法正常工作。 它是关于ORDER BY子句的。我正在尝试使用名为“sortby”的变量进行排序。
此处,现在使用DECODE()函数选择ORDER BY子句作为单独的列(,如@devio在此问题的原始版本中的回答中所建议的那样)。
在这种情况下,让我们说sortby ='memberCount',我把它作为decode()中的第一个参数传递给我; memberCount 是grptest表中的COLUMN。
select distinct gl.group_id,
decode('memberCount', 'name', gl.group_name_key,
'description', gl.group_description_key,
'memberCount', gl.member_count)
as p_sortby,
gl.group_name,
gl.group_description,
gl.status_code,
gl.member_count,
(select grpp.group_name
from grptest_relationship grel join grptest grpp
on grel.parent_group_id = grpp.group_id
where grel.child_group_id = gl.group_id) as parent_group_name,
gl.group_name_key,
gl.group_description_key
from grptest gl
where gl.group_org_id = '3909'
and (gl.group_name_key like '%' || 'GROUP' || '%')
order by 2;
它不起作用。
但是如果我在上面的解码中将'name'作为第一个参数传递,它就可以了。 这是我原来的问题,为什么它不适用于memberCount。
答案 0 :(得分:2)
我评论道:
你得到的错误是什么?或者你得到的错误行为是什么?在我的问题适应我的数据库时,我必须确保在DECODE()可接受之前将数字列转换为字符类型 - 其他两列是字符列。完成后,以及在“79”之后和“80”之前按字母顺序排序数字的次要问题,我得到了一个合适的结果。
罗希特问:
感谢您的投入。我想我对你提到的那个小问题感到困惑,“在'79'之后和'80'之前按字母顺序排序数字'8'。”我不知道这里有什么东西?另外,您可以帮我查询“在DECODE()可接受之前如何确保将数字列转换为字符类型”。你可以在这方面修改我上面的查询吗?
我使用的表是'元素表':
-- Tables for storing information about chemical elements and chemical compounds
-- See: http://www.webelements.com/ for elements.
-- See: http://ie.lbl.gov/education/isotopes.htm for isotopes.
CREATE TABLE elements
(
atomic_number INTEGER NOT NULL UNIQUE
CHECK (atomic_number > 0 AND atomic_number < 120),
symbol CHAR(3) NOT NULL UNIQUE,
name CHAR(20) NOT NULL UNIQUE,
atomic_weight DECIMAL(8,4) NOT NULL,
stable CHAR(1) DEFAULT 'Y' NOT NULL
CHECK (stable IN ('Y', 'N'))
);
这是一个有趣的表,因为它有三个真正的候选键(原子序数,名称和符号各自唯一),并且根据上下文(同位素与化学品),最好使用原子序数或符号作为连接键。
我使用的查询是:
select decode('atomic_number',
'name', name,
'symbol', symbol,
'atomic_number', atomic_number||''),
name, symbol, atomic_number
from elements
order by 1;
select decode('name',
'name', name,
'symbol', symbol,
'atomic_number', atomic_number||''),
name, symbol, atomic_number
from elements
order by 1;
select decode('symbol',
'name', name,
'symbol', symbol,
'atomic_number', atomic_number||''),
name, symbol, atomic_number
from elements
order by 1;
这些证明了三个排序 - 按符号,按名称和原子序数。
原子序数排序的部分结果集是:
77 Iridium Ir 77
78 Platinum Pt 78
79 Gold Au 79
8 Oxygen O 8
80 Mercury Hg 80
81 Thallium Tl 81
因为原子序数被强制转换为字符串,所以排序按字符串顺序排列,当被视为字符串时,'8'出现在'79'之后和'80'之前,如图所示。避免这个问题的一种方法是:
select decode('atomic_number',
'name', name,
'symbol', symbol,
'atomic_number', lpad(atomic_number, 3)),
name, symbol, atomic_number
from elements
order by 1;
生成以下内容(虽然不明显,但在第一列的开头有一个额外的空白):
77 Iridium Ir 77
78 Platinum Pt 78
79 Gold Au 79
80 Mercury Hg 80
81 Thallium Tl 81
82 Lead Pb 82
这使用空间在(ASCII,Latin-1,Unicode)排序序列中任何数字之前的知识,并且原子序数不超过3位。或者,我可以使用“LPAD(atomic_number, 3, '0')
”来填充数据。我在Solaris 10上使用IBM Informix Dynamic Server(IDS)11.50.FC3W2进行了测试.IDS非常容忍类型不匹配,并自动将atomic_number参数转换为LPAD为字符串。其他DBMS可能不那么宽容;你必须明确地施放价值。
回到问题......
假设memberCount是一个数字列且值不超过4位数(如果它们更长则适当调整),可以写入查询:
select distinct gl.group_id,
decode('memberCount', 'name', gl.group_name_key,
'description', gl.group_description_key,
'memberCount', LPAD(gl.member_count, 4))
as p_sortby,
gl.group_name,
gl.group_description,
gl.status_code,
gl.member_count,
(select grpp.group_name
from grptest_relationship grel join grptest grpp
on grel.parent_group_id = grpp.group_id
where grel.child_group_id = gl.group_id) as parent_group_name,
gl.group_name_key,
gl.group_description_key
from grptest gl
where gl.group_org_id = '3909'
and (gl.group_name_key like '%' || 'GROUP' || '%')
order by 2;
或者您可能需要:
LPAD(CAST(memberCount AS CHAR(4)), 4)
或其他一些略微DBMS特定的咒语,可以达到同样的效果。
由于您没有为查询提供架构(更少的示例数据),因此我的数据库中没有您的表,因此我无法演示您的查询工作
答案 1 :(得分:0)
我知道
order by p_sortby
不会工作,但你可以试试
order by decode('memberCount',
'name', gl.group_name_key,
'description', gl.group_description_key,
'memberCount', gl.member_count)
编辑:
我记得另一种方式:
select * from (
select column1, decode(....) as column2, .... from table1
) t1
order by 2
这种方式甚至可能更快