我正在为面向数据库的web应用程序构建查询,并遇到SELECT DISTINCT和ORDER BY的问题。我希望显示的第一个项目由一个变量确定(显示用户以前选择的选项),然后其余的正常排序。在我向选择添加DISTINCT选项(需要消除重复项)之前,我的ORDER BY工作得很好。被排序的列出现在我的SELECT中,所以我不确定为什么它不接受它。
WITH COURSE2 AS
(
SELECT DISTINCT(SUBSTRING(section_table.crs_cde, 1, 10)) AS CRSID, yr_cde, trm_Cde FROM section_table
)
SELECT DISTINCT crs_cde, crs_title
FROM course_table
LEFT JOIN COURSE2
ON crs_cde = CRSID
WHERE yr_cde = #currentyear#
AND trm_cde = #currentterm#
ORDER BY <cfif isDefined("FORM.ndd")>(case crs_cde when '#FORM.ndd#' then 0 else 1 end),</cfif> crs_cde ASC
感谢所有的帮助:)
被排序的列出现在我的SELECT
不完全是。仅仅在CASE
语句中使用相同的列之一不算数。ORDER BY引用必须与SELECT列表完全匹配。一种替代方法是将CASE移动到SELECT列表中,作为一个新列。然后按列别名:
SELECT DISTINCT crs_cde
, crs_title
, CASE crs_cde WHEN 'some value' THEN 0 ELSE 1 END AS SortOrder
FROM ...
ORDER BY SortOrder, crs_cde
关于查询的其他几个注释:
WHERE yr_cde = #currentyear#
AND trm_cde = #currentterm#
这将导致查询被转换为INNER JOIN。如果确实需要外部连接,请将这些过滤器移到CTE语句中。
确保在
cfqueryparam
中包装所有变量参数。在查询中使用原始变量会使数据库面临sql注入的风险。为了清晰和可读性,考虑添加表别名,并使用它们作为连接查询中所有列的前缀。
作用于所有变量,即使用
FORM.someField
而不是someField
把它们放在一起,像这样(未测试)
WITH COURSE2 AS
(
SELECT DISTINCT(SUBSTRING(crs_cde, 1, 10)) AS CRSID
FROM section_table
WHERE yr_cde = <cfqueryparam value="#FORM.currentYear#" cfsqltype="cf_sql_integer">
AND trm_cde = <cfqueryparam value="#FORM.currentTerm#" cfsqltype="cf_sql_integer">
)
SELECT DISTINCT ct.crs_cde
, ct.crs_title
<cfif structKeyExists(FORM, "ndd")>
, CASE ct.crs_cde
WHEN <cfqueryparam value="#FORM.ndd#" cfsqltype="cf_sql_varchar"> THEN 0
ELSE 1
END AS SortOrder
</cfif>
FROM course_table ct LEFT JOIN COURSE2 c2 ON c2.CRSID = ct.crs_cde
ORDER BY
<cfif structKeyExists(FORM, "ndd")>SortOrder,</cfif>
crs_cde ASC