在SQL中排序CTE的结果

时间:2013-08-20 06:20:05

标签: sql sql-server tsql

我有以下SQL:

;WITH CTE 
     AS (SELECT AL.*, 
                RV.FORENAME, 
                RV.SURNAME, 
                RV.USERNAME                  AS RegistrantUsername, 
                E.FORENAME                   AS EmployeeForename, 
                E.SURNAME                    AS EmployeeSurname, 
                U.USERNAME, 
                CASE 
                  WHEN @Language = 2 THEN C.NAMELANG2 
                  ELSE C.NAMELANG1 
                END                          AS CompanyName, 
                CASE 
                  WHEN VC.COMPANYID IS NULL THEN 
                    CASE 
                      WHEN @Language = 2 THEN V.COMPANYNAMELANG2 
                      ELSE V.COMPANYNAMELANG1 
                    END 
                  ELSE 
                    CASE 
                      WHEN @Language = 2 THEN VC.NAMELANG2 
                      ELSE VC.NAMELANG1 
                    END 
                END                          AS VacancyCompanyName, 
                CASE 
                  WHEN @Language = 2 THEN V.JOBTITLELANG2 
                  ELSE V.JOBTITLELANG1 
                END                          AS JobTitle, 
                ROW_NUMBER() 
                  OVER( 
                    PARTITION BY AL.REGISTRANTID, AL.COMPANYID 
                    ORDER BY ACTIONDATE ASC) AS RN 
         FROM   DBO.HR_ACTIONLOG AL 
                LEFT OUTER JOIN DBO.REGISTRANTSLISTVIEW RV 
                             ON AL.REGISTRANTID = RV.REGISTRANTID 
                LEFT OUTER JOIN DBO.HR_EMPLOYEES E 
                             ON AL.EMPLOYEEID = E.EMPLOYEEID 
                LEFT OUTER JOIN DBO.HR_USERS U 
                             ON AL.USERID = U.USERID 
                LEFT OUTER JOIN DBO.HR_COMPANIES C 
                             ON AL.COMPANYID = C.COMPANYID 
                LEFT OUTER JOIN DBO.HR_VACANCIES V 
                             ON AL.VACANCYID = V.VACANCYID 
                LEFT OUTER JOIN DBO.HR_COMPANIES VC 
                             ON V.COMPANYID = VC.COMPANYID 
         WHERE  ( @Action IS NULL 
                   OR AL.ACTION = @Action ) 
                AND ( @DateFrom IS NULL 
                       OR DBO.DATEONLY(AL.ACTIONDATE) >= 
                    DBO.DATEONLY(@DateFrom) ) 
                AND ( @DateTo IS NULL 
                       OR DBO.DATEONLY(AL.ACTIONDATE) <= DBO.DATEONLY(@DateTo) ) 
                AND ( @CompanyID IS NULL 
                       OR AL.COMPANYID = @CompanyID ) 
                AND ( @RegistrantID IS NULL 
                       OR AL.REGISTRANTID = @RegistrantID ) 
                AND ( @VacancyID IS NULL 
                       OR AL.VACANCYID = @VacancyID ) 
        --ORDER BY AL.ActionDate DESC 
        ) 
SELECT * 
FROM   CTE 
WHERE  RN = 1; 

它返回基于actiondate的组中的第一个元素,但是返回的结果没有按日期排序意味着返回每个组的第一个记录,但是这个第一个记录的集合没有按行动日期排序。我在CTE中尝试了ORDER BY AL.ActionDate DESC,但它给出了错误:

The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP or FOR XML is also specified.

5 个答案:

答案 0 :(得分:2)

order by子句移到cte:

之外
WITH CTE AS 
(
    ...
)
SELECT *
FROM CTE
WHERE RN = 1;
ORDER BY ActionDate DESC

答案 1 :(得分:2)

您在CTE

之外进行排序
WITH CTE
AS
{
 ....
}
SELECT *
FROM CTE
WHERE RN = 1
ORDER BY ActionDate DESC

答案 2 :(得分:2)

试试这个 -

;WITH CTE AS
(
    SELECT  ...
    FROM dbo.hr_ActionLog AL
    LEFT JOIN ...
    WHERE AL.[Action] = ISNULL(@Action, AL.[Action])
        AND dbo.DateOnly(AL.ActionDate) BETWEEN 
            dbo.DateOnly(ISNULL(@DateFrom, AL.ActionDate))
            AND
            dbo.DateOnly(ISNULL(@DateTo, '30000101'))
        AND AL.CompanyID = ISNULL(@CompanyID, AL.CompanyID)
        AND AL.RegistrantID = ISNULL(@RegistrantID, AL.RegistrantID)
        AND AL.VacancyID = ISNULL(@VacancyID, AL.VacancyID)
)
SELECT *
FROM CTE
WHERE RN = 1
ORDER BY AL.ActionDate DESC;

答案 3 :(得分:2)

是的,影响结果返回顺序的唯一ORDER BY是放在最外面的SELECT上的SELECT * FROM CTE WHERE RN = 1 ORDER BY ActionDate DESC

{{1}}

答案 4 :(得分:0)

CTE中有ROW_NUMBER个功能,查询只占用RN=1行。
如果我正确理解了问题,只需更改ORDER BY函数中的ROW_NUMBER子句,就可以得到您正在寻找的结果。