如何动态地在asc和desc中排序2个SQL字段

时间:2011-02-14 14:20:22

标签: sql sql-server sql-order-by

我想订购SQL Select查询,其中有2个字段按顺序排列。然后我需要决定一个是降序而另一个是升序。这是怎么做的

我想要类似的东西:

Select * from Customer
Order By Date @asc_or_Desc_date, Name @asc_or_Desc_name

有人有任何想法吗?

我试过这个,但似乎失败了

SELECT 

    Customer_ID,                        
    Name,                               
    Age                                         

FROM #Customer
ORDER BY 

    CASE WHEN @fieldSort ='Name'
        THEN ROW_NUMBER() over (order by Name) * 
            case when @directionOfSort = 'A' 
                THEN 1 ELSE -1 END,
             ROW_NUMBER() over (order by Age) * 
            case when @directionOfSort = 'A' 
                THEN 1 ELSE -1 END,
        END

任何人都知道如何对此进行排序?

4 个答案:

答案 0 :(得分:5)

SELECT 
  Customer_ID,                        
  Name,                               
  Age                                         
FROM
  #Customer
ORDER BY 
  CASE WHEN @field = 'Name' AND @direction = 'A' THEN Name ELSE NULL END ASC,
  CASE WHEN @field = 'Name' AND @direction = 'D' THEN Name ELSE NULL END DESC,
  CASE WHEN @field = 'Age'  AND @direction = 'A' THEN Age  ELSE NULL END ASC,
  CASE WHEN @field = 'Age'  AND @direction = 'D' THEN Age  ELSE NULL END DESC


我不想在许多不同的组合中这样做。如果你有很多组合,我会根据以下内容做一些...

SELECT 
  Customer_ID,                        
  Name,                               
  Age                                         
FROM
(
  SELECT
    Customer_ID,
    Name,
    ROW_NUMBER() OVER (ORDER BY Name) AS "name_order",
    Age,
    ROW_NUMBER() OVER (ORDER BY Age)  AS "age_order"
  FROM
    #Customer
)
  AS [data]
ORDER BY 
  CASE @field1
    WHEN 'Name' THEN CASE @direction1 WHEN 'A' THEN name_order ELSE -name_order END
    WHEN 'Age'  THEN CASE @direction1 WHEN 'A' THEN age_order  ELSE -age_order  END
    ELSE NULL
  END,
  CASE @field2
    WHEN 'Name' THEN CASE @direction2 WHEN 'A' THEN name_order ELSE -name_order END
    WHEN 'Age'  THEN CASE @direction2 WHEN 'A' THEN age_order  ELSE -age_order  END
    ELSE NULL
  END

根据需要重复多次......


注意:仅仅因为它可以通过这种方式完成,并不意味着它应该以这种方式完成。

答案 1 :(得分:3)

您必须动态创建SQL语句才能使用变量:

DECLARE @asc_desc VARCHAR(4);

SET @asc_desc = 'DESC';

DECLARE @sql NVARCHAR(1000);

SET @sql = 'Select * from Customer Order By Date ' + @asc_desc + ', Name';

EXEC sp_executesql @sql

这将订购日期DESCENDING和姓名ASCENDING

如果您要使用DESC,则只需添加DESCENDING,因为ASCENDING是默认设置。

答案 2 :(得分:2)

在SQL Server 2005+中,您可以使用以下设备:

WITH CustomerCTE AS (
  SELECT
    *,
    DateSort = ROW_NUMBER() OVER (ORDER BY Date),
    NameSort = ROW_NUMBER() OVER (ORDER BY Name)
  FROM Customer
)
SELECT *
FROM CustomerCTE
ORDER BY DateSort * @DateSortDir, NameSort * @NameSortDir

此案例中的变量应为1-1


修改

另外发布的示例似乎暗示在ORDER BY中使用的列的顺序也应该是动态的。现在看来,两列的统一指定了顺序方向。

是否是这样(问题变得有点模棱两可),两者都在我的第二个解决方案中假设。

DECLARE @IntSortDir int;
SET @IntSortDir = CASE @directionOfSort WHEN 'A' THEN 1 ELSE -1 END;

WITH CustomerCTE AS (
  SELECT
    Customer_ID,
    Name,
    Age,
    NameSort = ROW_NUMBER() OVER (ORDER BY Name),
    AgeSort  = ROW_NUMBER() OVER (ORDER BY Date)
  FROM Customer
)
SELECT
  Customer_ID,
  Name,
  Age
FROM CustomerCTE
ORDER BY
  CASE @fieldSort WHEN 'Age' THEN AgeSort END * @IntSortDir,
  NameSort * @directionOfSort,
  CASE @fieldSort WHEN 'Name' THEN AgeSort END * @IntSortDir

@fieldSort指定主要订单列。另一个自动成为次要的。

答案 3 :(得分:1)

Here is the solution

Explanation:
1. Ordering the row number on the basis of SQL input param  order by (DESC, ASC)
2. Againt ordering the row number in outer query

Try this code (working)

DECLARE @PageNum int
DECLARE @PageSize int
DECLARE @TotalRowsNum int
DECLARE @SortColumn varchar(200)
DECLARE @SortOrder varchar(5)

SET @PageNum = 4;
SET @PageSize = 10;
SET @SortColumn = 'CODE_ID';
SET @SortOrder = 'DESC';

WITH QueryResult AS
(

SELECT *,
CASE @SortOrder WHEN 'ASC' THEN
ROW_NUMBER() OVER(ORDER BY @SortColumn ASC) 
ELSE
ROW_NUMBER() OVER(ORDER BY @SortColumn DESC) 
END AS 'RowNumber'

FROM TABLE_NAME 
) 
SELECT * FROM QueryResult
WHERE RowNumber BETWEEN (@PageNum - 1) * @PageSize + 1 AND @PageNum * @PageSize
ORDER BY RowNumber ASC