我有一个查询根据第二列对结果进行排序。
select decode(name, null, 'n/a', name) name, value1
from tableA
group by name
order by 2
如何更改它,以便第一列为null的结果始终是结果集中的最后一行,而不更改其余结果的排序?
我想到的一个解决方案是使用union两个查询,一个排除null,另一个只有null,如:
select decode(name, null, 'n/a', name) name, value1
from tableA
where name is not null
group by name
union
select decode(name, null, 'n/a', name) name, value1
from tableA
where name is null
group by name
order by 2
有更好的方法吗?
答案 0 :(得分:2)
您的union
方法无法获得您想要的结果;联合两个查询后应用order by
,因此它们的排序方式与单个查询相同。您可以在联合的每个brach中添加一个标志列,并在排序中包含该列,但您需要将其从最终选择列表中排除。
您可以在order by clause
中使用case语句(或者如果您愿意,可以解码)来处理第1列,它将所有非空值视为一个优先级而不管实际值,并将所有空值视为不同的优先事项;然后按第2栏进一步下单:
select decode(a.name, null, 'n/a', a.name) name, value1
from tableA a
order by case when a.name is null then 1 else 0 end, value1 desc
我已经使用了表别名,并且包括在这种情况下,以避免原始表值与同名列别名之间的混淆。这将使所有结果在所有非空的名称之后带有空(' n / a')名称;在每个类别中,所有结果仍将按第二列排序。
使用一些示例数据:
with tableA (name, value1) as (
select 'Joe', 3 from dual
union all select 'Anne', 10 from dual
union all select null, 4 from dual
union all select 'Sarah', 2 from dual
union all select 'Bill', 5 from dual
union all select 'Mary', 7 from dual
)
...仅按第二列排序:
select decode(a.name, null, 'n/a', a.name) name, value1
from tableA a
order by value1 desc;
NAME VALUE1
----- ----------
Anne 10
Mary 7
Bill 5
n/a 4
Joe 3
Sarah 2
添加此案例条款会使您的' n / a'结果集中的最后一行:
select decode(a.name, null, 'n/a', a.name) name, value1
from tableA a
order by case when a.name is null then 1 else 0 end, value1 desc;
NAME VALUE1
----- ----------
Anne 10
Mary 7
Bill 5
Joe 3
Sarah 2
n/a 4
(我在您的示例中忽略了group by子句,因为您没有任何聚合,并且您的查询都没有效;但是如果您仍然可以在真实查询中进行分组和执行此操作需要。)