как заказать 2 поля SQL в asc и desc динамически - PullRequest
5 голосов
/ 14 февраля 2011

Я хочу заказать SQL Select Query, где есть 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 ]

5 голосов
/ 14 февраля 2011
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

Повторите столько раз, сколько требуется ...


Примечание : То, что это можно сделать таким образом, не означает, что это следует делать таким образом.

3 голосов
/ 14 февраля 2011

Вам нужно будет динамически создавать оператор 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 голосов
/ 14 февраля 2011

В 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 указывает столбец первичного заказа.Другой автоматически становится второстепенным.

1 голос
/ 01 марта 2012
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 
...