Sql 忽略ORDERBY子句中的空值
编辑:我已将字符更改为整数,以更好地表示我的问题-不确定它是否会对实际的Sql 忽略ORDERBY子句中的空值,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,编辑:我已将字符更改为整数,以更好地表示我的问题-不确定它是否会对实际的ORDER BY子句产生影响。原始数据集可以在这个问题的底部找到 是否可以忽略ORDER BY子句中的空值 我运行了一个查询,该查询当前提供以下信息: COL1 COL2 COL3 ----------------------- 111 111 100 112 NULL 200 113 115 100 NULL 112 400 NUL
ORDER BY
子句产生影响。原始数据集可以在这个问题的底部找到
是否可以忽略ORDER BY子句
中的空值
我运行了一个查询,该查询当前提供以下信息:
COL1 COL2 COL3
-----------------------
111 111 100
112 NULL 200
113 115 100
NULL 112 400
NULL 114 250
但我想让它看起来像这样:
COL1 COL2 COL3
-----------------------
111 111 100
NULL 112 400
112 NULL 200
NULL 114 250
113 115 100
我希望ORDER BY忽略COL1
中的null
。
但我还是要按每一列排序
按COL1、COL2、COL3排序
原始数据集
COL1 COL2 COL3
-----------------------
111 AAA 100
112 NULL 200
113 EEE 100
NULL BBB 400
NULL DDD 250
下面是一个例子:
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
*/
下面是一个例子:
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
*/
SQL Server无法按您的意愿返回结果集。它没有任何信息告诉它,同样包含“BBB”和400的记录上COL1的空值介于111和112之间。排序具有优先顺序,并且仅当前面的子句值中存在匹配项时,才会使用第二和第三排序子句。SQL Server无法按您的意愿返回结果集。它没有任何信息告诉它,同样包含“BBB”和400的记录上COL1的空值介于111和112之间。排序有一个优先顺序,只有在前面的子句值中存在匹配项时,才会使用第二和第三排序子句。编辑:查看后,我不确定OP想要的结果集是否可能没有一个严格特定的(可能是嵌套的)结果集
orderby
中的CASE
语句,因为就SQL而言,所需的输出实际上不是以可预测的方式排序的
由于没有可靠的方法可以让SQL在不使用所有可能的空条件硬编码订单的情况下执行此操作,因此我不建议对任何类型的生产查询或过程执行此操作,但对于一次性查询,您可以通过滥用SQL Server中的
ISNULL
或函数来获取所需的数据:
ORDER BY ISNULL(CONVERT(varchar, COL1), ISNULL(COL2, (CONVERT(varchar, COL3))))
基本上,您创建订单层次结构时会说,“order by COL1。如果为null,则使用COL2。如果为null,则使用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零200
113 EEE 100
空BBB400
空DDD 250
如果便于阅读,您还可以在排序依据
中使用CASE
语句:
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就无法给出这样的结果。编辑:在回顾之后,我不确定OP想要的结果集是否可能没有严格特定的(并且可能是嵌套的)
orderby
中的CASE
语句,因为就SQL而言,所需的输出实际上不是以可预测的方式排序的
由于没有可靠的方法可以让SQL在不使用所有可能的空条件硬编码订单的情况下执行此操作,因此我不建议对任何类型的生产查询或过程执行此操作,但对于一次性查询,您可以通过滥用SQL Server中的
ISNULL
或函数来获取所需的数据:
ORDER BY ISNULL(CONVERT(varchar, COL1), ISNULL(COL2, (CONVERT(varchar, COL3))))
基本上,您创建订单层次结构时会说,“order by COL1。如果为null,则使用COL2。如果为null,则使用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零200
113 EEE 100
空BBB400
空DDD 250
如果便于阅读,您还可以在排序依据
中使用CASE
语句:
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就无法给出这样的结果。我最接近的方法就是这个
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
我最接近的地方就是这里
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
根据您提供的数据样本,
ORDER BY COL2
似乎正是您想要的。它不起作用,因为我需要先按COL1排序,然后按COL2显示一些更具代表性的数据。现在Col3看起来是最好的选择。如果不先在其他地方排序,就无法知道112应该是COL1中的第三行,因为第2行和第4行中有空值。然后你需要先按Col2或Col3订购,但你是说你需要先按Col1订购…所以简单回答:不。根据你提供的数据样本,ORDER BY COL2
似乎正是您想要的。它不起作用,因为我需要先按COL1排序,然后按COL2显示一些更具代表性的数据。现在Col3看起来是最好的选择。如果不先在其他地方排序,就无法知道112应该是COL1中的第三行,因为第2行和第4行中有空值。然后你需要先按Col2或Col3订购,但你是说你需要先按Col1订购…所以简短的回答:不。谢谢你的回答-它看起来几乎在那里,除了Col2
在你的结果中没有排序,但是Col1看起来不错。有没有可能用你的方法来订购COL2?你是对的,我没有注意到。现在我仔细看看,我认为罗伯·爱泼斯坦可能是对的。除非你用utra的特定条件做了一个大规模的案例,否则我认为这是不可能的。即使您用一些任意值替换了NULLS
,结果集也不是真正有序的。感谢您的回答-它看起来几乎在那里,除了COL2
在您的结果中不是有序的,但是COL1看起来不错。有没有可能用你的方法来订购COL2?你是对的,我没有注意到。现在我仔细看看,我认为罗伯·爱泼斯坦可能是对的。除非您使用utra特定的