以下查询返回错误。帮助我根据错误以及实现条件排序的方式。我试图按年级和名称排序(当年级> = 8时排序),并按等级和分数(当年级<8)时评分。
SELECT
name, grade, marks
FROM
students, grades
WHERE
min_mark <= marks
AND marks <= max_mark
AND marks >= 70
UNION
SELECT
TO_CHAR('NULL') AS name, grade, marks
FROM
students, grades
WHERE
min_mark <= marks
AND marks <= max_mark
AND marks <= 69
order by grade desc,(case when grade >= 8
then name
when grade < 8
then marks
end );
错误:
按等级desc排序(等级> = 8
的情况 *
第18行出现错误:
ORA-01785:ORDER BY项目必须是SELECT列表表达式的编号
答案 0 :(得分:1)
这似乎是错误5695629,它似乎是针对10g提出的,并且似乎尚未修复(截至12cR2;我还没有18可以玩),这是不寻常的。 / p>
可以通过在订购前将查询包装在外部选择中来避免这种情况:
select name, grade, marks
from
(
SELECT
name, grade, marks
FROM
students, grades
WHERE
min_mark <= marks
AND marks <= max_mark
AND marks >= 70
UNION
SELECT
TO_CHAR('NULL') AS name, grade, marks
FROM
students, grades
WHERE
min_mark <= marks
AND marks <= max_mark
AND marks <= 69
)
order by grade desc,case when grade >= 1
then name
when grade < 1
then marks
end ;
但是由于name
和marks
是(大概)不同的数据类型-字符串和数字-而是会得到
ORA-00932:数据类型不一致:预期的CHAR得到了NUMBER
您可以将marks
转换为字符串,但是如果这样做,则需要对其进行填充,以便按字母顺序对结果字符串进行排序仍与数字顺序匹配-混乱但合理,因为标记可以(再次,大概-这是一个百分比?)最多只能是三位数:
select name, grade, marks
from
(
...
<the main part of your query here as a subquery, as above>
...
)
order by grade desc,case when grade >= 8
then name
when grade < 8
then to_char(marks, 'FM000')
end ;
db<>fiddle demo使用通过CTE提供的一些虚拟数据。
如果标记可以超过三位数,则更改格式掩码以匹配最大可能长度。
TO_CHAR('NULL')
部分也很奇怪,因为它将在名称列中为这些行提供文字字符串“ NULL”。由于您以字符串文字开头,TO_CHAR()
部分毫无意义,因此直接使用'NULL' AS name
。如果实际上希望它为空,则可以使用null AS name
,它将与联合的第一个分支中的匹配列表达式的数据类型相匹配(并且也将选择其别名)。您可以显式转换为字符串类型,例如cast(null as varchar2(20)) AS name
,但似乎没有多大意义。
答案 1 :(得分:0)
SQL中CASE Expressions有2种形式。
CASE <expression> WHEN <v1> THEN <ret1> WHEN <v2> THEN <ret2> ... END
另一个是
CASE WHEN <comp1> THEN <ret1> WHEN <comp2> THEN <ret2> ... END
区别在于,在情况1中,您指定了要比较一次的值或表达式,然后将其与其他值或表达式进行比较,与变量2一样,您为每个WHEN指定了一个比较表达式。
将表达式更改为
CASE WHEN grade >= 8 THEN name ELSE TO_CHAR(marks, '0999999999') END
我还将标记数字格式化为带有前导零的字符串,以使其可以与名称一起作为文本进行排序。