我们在sql server中进行排序时如何处理空值

时间:2013-08-21 14:36:06

标签: sql-server sql-server-2008 tsql sql-order-by sql-server-2012

我正在尝试使用以下查询按列排序,列中包含空值,例如将参数传递给存储过程以及排序方向并按列排序作为输入参数

ALTER PROCEDURE [dbo].[tp_SelectTransactionHistorySearch]
(
   @OffSetRowNo INT,     
   @FetchRowNo INT,
   @StatusSelection NVARCHAR(MAX),
   @IsReviewed Bit,
   @ProjectCaseNumber VARCHAR(MAX),
   @CostPageNumber VARCHAR(MAX),
   @TransactionTypeChange VARCHAR(MAX),
   @DescriptionChange VARCHAR(MAX),
   @TrasactionCreateOnBeginDate DATE,
   @TransactionCreatedOnEndDate DATE,
   @TransactionUpdatedOnBeginDate DATE,
   @TransactionUpdateOnEndDate DATE,
   @ItemID VARCHAR(MAX),
   @SortOrder VARCHAR(MAX),
   @SortByColumnName VARCHAR(MAX)
)
AS

  SELECT 
        TransactionID,IsReviewed,ItemID,CostPageNumber,Comments,
        CreatedBy,CreatedDateTime,UpdatedBy,UpdatedDateTime,
        TransactionDescription,TransactionTypeID,PROJCASE,
        TransactionStatusID, TransactionStatusTypeName,
        TransactionStatusTypeDescription,    
        TransactionTypeName, TransactionTypeDescription,
        COUNT(*) OVER () as TotalCount
 FROM
 ( //select
  //  union
  //  select
  //  union  
   //like select statement from union results
 ) ResultSet
      //here i am doing sorting 
     ORDER BY
 CASE @SortOrder 
    WHEN 'ASC' THEN  
       CASE @SortByColumnName
         WHEN 'TransactionID' THEN CONVERT(VARCHAR(MAX), ResultSet.TransactionID)
         WHEN 'ItemID' THEN CONVERT(VARCHAR(MAX), ResultSet.ItemID)
         WHEN 'CostPageNumber' THEN ResultSet.CostPageNumber
         WHEN 'Comments' THEN ResultSet.Comments
         WHEN 'CreatedBy' THEN ResultSet.CreatedBy
         WHEN 'CreatedDateTime' THEN  CONVERT(VARCHAR(MAX), ResultSet.CreatedDateTime)
         WHEN 'UpdatedBy' THEN ResultSet.UpdatedBy
         WHEN 'UpdatedDateTime' THEN  CONVERT(VARCHAR(MAX), ResultSet.UpdatedDateTime)
         WHEN 'TransactionDescription' THEN ResultSet.TransactionDescription
         WHEN 'TransactionTypeName' THEN ResultSet.TransactionTypeName
         WHEN 'PROJCASE' THEN ResultSet.PROJCASE
         WHEN 'TransactionStatusTypeName' THEN ResultSet.TransactionStatusTypeName
         WHEN 'TransactionStatusTypeDescription' THEN ResultSet.TransactionStatusTypeDescription
       END 
  END 
  ASC, 
 CASE @SortOrder 
    WHEN 'DESC' THEN              
       CASE @SortByColumnName
         WHEN 'TransactionID' THEN  CONVERT(VARCHAR(MAX), ResultSet.TransactionID)
         WHEN 'ItemID' THEN CONVERT(VARCHAR(MAX), ResultSet.ItemID)
         WHEN 'CostPageNumber' THEN ResultSet.CostPageNumber
         WHEN 'Comments' THEN ResultSet.Comments
         WHEN 'CreatedBy' THEN ResultSet.CreatedBy
         WHEN 'CreatedDateTime' THEN CONVERT(VARCHAR(MAX), ResultSet.CreatedDateTime)
         WHEN 'UpdatedBy' THEN ResultSet.UpdatedBy
         WHEN 'UpdatedDateTime' THEN CONVERT(VARCHAR(MAX), ResultSet.UpdatedDateTime)
         WHEN 'TransactionDescription' THEN ResultSet.TransactionDescription
         WHEN 'TransactionTypeName' THEN ResultSet.TransactionTypeName
         WHEN 'PROJCASE' THEN ResultSet.PROJCASE
         WHEN 'TransactionStatusTypeName' THEN ResultSet.TransactionStatusTypeName
         WHEN 'TransactionStatusTypeDescription' THEN ResultSet.TransactionStatusTypeDescription
       END 
 END 
 OFFSET ( @OffSetRowNo-1 ) * @FetchRowNo ROWS
    FETCH NEXT @FetchRowNo ROWS ONLY

这里没有使用任何orderBy(排序方法)我得到two rows作为结果,即使它们是列中的空值但是有排序(即)OrderBy我只能获得一行结果 并且我不确定如何在使用order by时处理null值,但我已尝试过以下语句

  WHEN ColumnB IS NULL THEN 1 ELSE 0 END ASC,

但是当应用这个时我得到语法错误.... 请问在任何情况下如何在这种情况下处理空值时提出任何想法。 我正在使用sql server 2012 Edition

非常感谢提前......

2 个答案:

答案 0 :(得分:1)

您是否尝试过使用内置ISNULL() - 函数?

ISNULL(ColumnB, 1)

答案 1 :(得分:1)

下面给出了动态排序顺序和排序字段的简化方案。

--TEST DATA
DECLARE @MYTable TABLE (EmpID INT, EmpName VARCHAR(10) , JoinDate DATETIME)

INSERT INTO @MYTable VALUES (1,'E1','1/1/2001');
INSERT INTO @MYTable VALUES (2,'E2','2/2/2002');
INSERT INTO @MYTable VALUES (3,'E3','5/5/2001');

--INPUT Parameters
DECLARE @SortParam VARCHAR(MAX)
SET @SortParam = 'JoinDate'

DECLARE @SortDirection VARCHAR(MAX)
SET @SortDirection = 'DESC'


--@RankTypeID Variable
DECLARE @RankTypeID  INT

--EMPNAME
IF (@SortParam = 'EmpName' AND @SortDirection = 'ASC')
BEGIN 
    SET @RankTypeID = 1 
END

IF (@SortParam = 'EmpName' AND @SortDirection = 'DESC')
BEGIN
    SET @RankTypeID = -1    
END

--EmpID
IF (@SortParam = 'EmpID' AND @SortDirection = 'ASC')
BEGIN 
    SET @RankTypeID = 2 
END

IF (@SortParam = 'EmpID' AND @SortDirection = 'DESC')
BEGIN
    SET @RankTypeID = -2
END

--JoinDate
IF (@SortParam = 'JoinDate' AND @SortDirection = 'ASC')
BEGIN 
    SET @RankTypeID = 3 
END

IF (@SortParam = 'JoinDate' AND @SortDirection = 'DESC')
BEGIN
    SET @RankTypeID = -3
END


-- SELECT
SELECT * 
FROM @MYTable M
ORDER BY 
        CASE @RankTypeID WHEN 1 then EmpName ELSE null end ASC,
        CASE @RankTypeID WHEN -1 then EmpName ELSE null end DESC,

        CASE @RankTypeID WHEN 2 then [EmpID] else null end ASC ,
        CASE @RankTypeID WHEN -2 then [EmpID] else null end DESC ,

        CASE @RankTypeID WHEN 3 then JoinDate else null end  ASC,
        CASE @RankTypeID WHEN -3 then JoinDate else null end  DESC


--END