在ORDER BY CLAUSE中忽略NULL

时间:2014-08-01 12:50:22

标签: sql sql-server sql-server-2008

编辑:我已将字符更改为整数以更好地表示我的问题 - 不确定它是否会对实际的ORDER BY条款产生影响。原始数据集可以在此问题的底部找到。

NULLS中是否可以忽略 ORDER BY CLAUSE

我有一个我跑的查询,目前给我这个:

COL1     COL2     COL3
-----------------------
111      111      100
112      NULL     200
113      115      100
NULL     112      400
NULL     114      250

但我希望ORDER BY看起来像这样:

COL1     COL2    COL3
-----------------------
111      111      100
NULL     112      400
112      NULL     200
NULL     114      250
113      115      100

我希望ORDER BY忽略NULLS中的COL1。 但是我仍然希望它按每列排序。

ORDER BY COL1, COL2, COL3


ORIGINAL DATASET

COL1     COL2     COL3
-----------------------
111      AAA      100
112      NULL     200
113      EEE      100
NULL     BBB      400
NULL     DDD      250

4 个答案:

答案 0 :(得分:2)

SQL Server无法根据需要返回结果集。它没有信息告诉它记录中COL1的NULL值也包含' BBB' 400在111和112之间。排序具有优先顺序,并且只有在前面的子句值匹配时才使用二级和三级排序子句。

答案 1 :(得分:2)

编辑:审核之后,如果CASE中没有严重的(可能是嵌套的)ORDER BY语句,我不确定OP所需的结果集是否可行因为就SQL而言,所需的输出实际上并没有以可预测的方式排序。


由于没有可靠的方法来让SQL在没有对每个可能的空条件进行硬编码的情况下执行此操作,因此我不建议对任何类型的生产查询或过程执行此操作,而是为了一次性查询,您可以通过滥用SQL Server中的ISNULLCOALESCE函数来获取所需的数据:

ORDER BY ISNULL(CONVERT(varchar, COL1), ISNULL(COL2, (CONVERT(varchar, COL3))))

基本上,您通过说“按COL1排序。创建订单层次结构。如果为空,请使用COL2。如果为空,请使用COL3”

以下是它的实际效果:

DECLARE @temp TABLE (COL1 int, COL2 varchar(10), COL3 int)

INSERT INTO @temp VALUES(111, 'AAA', 100)
INSERT INTO @temp VALUES(112, NULL, 200)
INSERT INTO @temp VALUES(113 , 'EEE', 100)
INSERT INTO @temp VALUES(NULL, 'BBB', 400)
INSERT INTO @temp VALUES(NULL,'DDD', 250)

SELECT * 
FROM @temp
ORDER BY ISNULL(CONVERT(varchar, COL1), ISNULL(COL2, (CONVERT(varchar, COL3))))

以下是结果:

  COL1  COL2  COL3
-------------------
  111   AAA   100
  112   NULL  200
  113   EEE   100
  NULL  BBB   400
  NULL  DDD   250

如果您更容易阅读,也可以在CASE中使用ORDER BY语句:

SELECT * 
FROM @temp
ORDER BY 
CASE
    WHEN COL1 IS NOT NULL 
        THEN CONVERT(varchar, COL1)
    WHEN COL2 IS NOT NULL 
        THEN COL2
    ELSE 
        CONVERT(varchar, COL3)
END

但是,我想再次强调,SQL没有真正的方法可以为您提供这样的结果而不会像这样硬编码。

答案 2 :(得分:0)

以下是示例:

DECLARE @table TABLE (COL1 INT, COL2 VARCHAR(100), COL3 INT)


INSERT INTO @table SELECT 111, 'AAA', 100
INSERT INTO @table SELECT NULL, 'BBB', 150
INSERT INTO @table SELECT 112, 'CCC', 200
INSERT INTO @table SELECT NULL, 'DDD', 250
INSERT INTO @table SELECT 113, 'EEE', 300




SELECT * 
FROM @table
ORDER BY CASE WHEN COL1 IS NULL THEN 999 ELSE COL1 END, COL2, COL3
/*result
COL1    COL2    COL3
111     AAA     100
112     CCC     200
113     EEE     300
NULL    BBB     150
NULL    DDD     250
*/

答案 3 :(得分:0)

我能找到的最近的是

DECLARE @temp TABLE (COL1 INT,
                 COL2 VARCHAR(10),
                 COL3 INT)

INSERT INTO @temp
VALUES(111, 'AAA', 100)
INSERT INTO @temp
VALUES(112, NULL, 200)
INSERT INTO @temp
VALUES(113 , 'EEE', 100)
INSERT INTO @temp
VALUES(NULL, 'BBB', 400)
INSERT INTO @temp
VALUES(NULL, 'DDD', 250)

SELECT COL1,
      COL2,
      COL1
FROM @temp
ORDER BY ISNULL(CAST(COL1 AS VARCHAR(10)), '') + ISNULL(COL2, '') + ISNULL(CAST(COL3 AS VARCHAR(10)), '')

<强>结果:

COL1    COL2    COL3
111     AAA     100
112     NULL    200
113     EEE     100
NULL    BBB     400
NULL    DDD     250