根据另一列为null更改结果集顺序

时间:2016-02-22 18:42:58

标签: sql oracle

我有一个查询根据第二列对结果进行排序。

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

有更好的方法吗?

1 个答案:

答案 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子句,因为您没有任何聚合,并且您的查询都没有效;但是如果您仍然可以在真实查询中进行分组和执行此操作需要。)