通过 "order by case" 声明协助订购

Assistance with order by "order by case" statement

我想知道是否有人可以帮助我解决我的“按案例排序”语句起作用的问题。下面是我嵌入到 SSRS 报告中的 SQL,但是当我 运行 它时,我收到以下错误消息:

ORDER BY items must appear in the select list if SELECT DISTINCT is specified. (Microsoft SQL Server, Error: 145)

   SELECT DISTINCT ppl.txtSchoolID,
       ppl.txtSurname,
       ppl.txtForename,
       ppl.txtGender,
       ppl.txtReligion,
       CASE COALESCE(pplFamily.intFamily, 0)
           WHEN 0 THEN 'N'
           ELSE 'Y'
       END AS [HasSiblings],
       ppl.txtDOB,
       DATEDIFF(yy, ppl.txtDOB, GETDATE()) - 
           CASE WHEN (MONTH(ppl.txtDOB) > MONTH(GETDATE()))
                  OR (MONTH(ppl.txtDOB) = MONTH(GETDATE()) 
                  AND DAY(ppl.txtDOB) > DAY(GETDATE())) THEN 1 
                ELSE 0 
           END AS [Age],
       CASE COALESCE(Internationals.txtValue, 'false')
             WHEN 'true' THEN 'Y'
             WHEN 'false' THEN 'N'
       END AS [International],
       ppl.txtType,
       ppl.intEnrolmentNCYear,
       schYears.txtYearName,
       ppl.txtEnrolmentTerm,
       ppl.intEnrolmentSchoolYear,
       ppl.txtBoardingHouse,
       ppl.txtNationality,
       ppl.txtAdmissionsStatus,
       ppl.txtEnrolmentAcademicHouse
FROM dbo.TblPupilManagementPupils AS ppl
     LEFT OUTER JOIN
     dbo.TblPupilManagementCustomFieldValue AS Internationals
     ON ppl.txtSchoolID = Internationals.txtSchoolId
     AND Internationals.intCustomFieldId = 14
     LEFT OUTER JOIN
     dbo.TblSchoolManagementYears AS schYears
     ON ppl.intEnrolmentNCYear = schYears.intNCYear
     LEFT OUTER JOIN
     (SELECT txtSchoolID, intFamily
      FROM dbo.TblPupilManagementPupils) AS pplFamily
     ON     pplFamily.intFamily = ppl.intFamily
        AND pplFamily.txtSchoolID <> ppl.txtSchoolID
WHERE (ppl.intEnrolmentSchoolYear IN (@AcademicYear))

ORDER BY CASE WHEN ppl.txtAdmissionsStatus = 'Registered' THEN 1
              WHEN ppl.txtAdmissionsStatus = 'Interviewed' THEN 2
              WHEN ppl.txtAdmissionsStatus = 'Offered' THEN 3
              WHEN ppl.txtAdmissionsStatus = 'Accepted' THEN 4
              ELSE 5 END

有谁能告诉我我做错了什么吗?

非常感谢。

斯图尔特

由于 DISTINCT 和 GROUP BY 的工作方式类似,因此您需要 SELECT 部分中可用的按顺序出现的所有内容。

整个案例陈述

CASE WHEN ppl.txtAdmissionsStatus = 'Registered' THEN 1
              WHEN ppl.txtAdmissionsStatus = 'Interviewed' THEN 2
              WHEN ppl.txtAdmissionsStatus = 'Offered' THEN 3
              WHEN ppl.txtAdmissionsStatus = 'Accepted' THEN 4
              ELSE 5 END

是一个新的计算列,在 SELECT DISTINCT 列表中不可用。你需要在那里添加它。请注意,此新列与可用的 ppl.txtAdmissionsStatus 不同。

因此您需要将 case 语句放在 SELECT 部分,如下所示。

您还可以参考 ORDER BY items must appear in the select list if SELECT DISTINCT is specified

上的多个答案
 SELECT DISTINCT ppl.txtSchoolID,
       ppl.txtSurname,
       ppl.txtForename,
       ppl.txtGender,
       ppl.txtReligion,
       CASE COALESCE(pplFamily.intFamily, 0)
           WHEN 0 THEN 'N'
           ELSE 'Y'
       END AS [HasSiblings],
       ppl.txtDOB,
       DATEDIFF(yy, ppl.txtDOB, GETDATE()) - 
           CASE WHEN (MONTH(ppl.txtDOB) > MONTH(GETDATE()))
                  OR (MONTH(ppl.txtDOB) = MONTH(GETDATE()) 
                  AND DAY(ppl.txtDOB) > DAY(GETDATE())) THEN 1 
                ELSE 0 
           END AS [Age],
       CASE COALESCE(Internationals.txtValue, 'false')
             WHEN 'true' THEN 'Y'
             WHEN 'false' THEN 'N'
       END AS [International],
       ppl.txtType,
       ppl.intEnrolmentNCYear,
       schYears.txtYearName,
       ppl.txtEnrolmentTerm,
       ppl.intEnrolmentSchoolYear,
       ppl.txtBoardingHouse,
       ppl.txtNationality,
       ppl.txtAdmissionsStatus,
       ppl.txtEnrolmentAcademicHouse, 
CASE WHEN ppl.txtAdmissionsStatus = 'Registered' THEN 1
              WHEN ppl.txtAdmissionsStatus = 'Interviewed' THEN 2
              WHEN ppl.txtAdmissionsStatus = 'Offered' THEN 3
              WHEN ppl.txtAdmissionsStatus = 'Accepted' THEN 4
              ELSE 5 END as AdmissionStatusKey
FROM dbo.TblPupilManagementPupils AS ppl
     LEFT OUTER JOIN
     dbo.TblPupilManagementCustomFieldValue AS Internationals
     ON ppl.txtSchoolID = Internationals.txtSchoolId
     AND Internationals.intCustomFieldId = 14
     LEFT OUTER JOIN
     dbo.TblSchoolManagementYears AS schYears
     ON ppl.intEnrolmentNCYear = schYears.intNCYear
     LEFT OUTER JOIN
     (SELECT txtSchoolID, intFamily
      FROM dbo.TblPupilManagementPupils) AS pplFamily
     ON     pplFamily.intFamily = ppl.intFamily
        AND pplFamily.txtSchoolID <> ppl.txtSchoolID
WHERE (ppl.intEnrolmentSchoolYear IN (@AcademicYear))

ORDER BY AdmissionStatusKey

如果 select 子句中没有 Case 表达式,则不能在 Order By 子句中使用它。 除了使用 Distinct,您还可以尝试使用 Group By。

正如其他人所说,您的 select 列表中需要 CASE 语句。

However:如果您在 SSRS 中使用它,则不需要 ORDER BY 子句,只需将 case 语句添加到 select 列表即可。 SSRS 将按照 tablix 行组定义的任何方式进行排序。

因此,将带有别名(例如 AdmissionsStatusOrder)的 CASE 语句添加到您的 select 列表中,您可以删除 ORDER BY 子句,因为这实际上作用不大,然后在您的报告中, 按新的 AdmissionsStatusOrder 列排序。