我正在使用Pro * C查询,但这个问题应该是通用SQL。我的研究已经走到了尽头,但我想我错过了一些东西。
假设我的服务器有一组学生姓名{"Alice","Charlie","Bob"}
。我在Student_Ids
表中查询学生的身份证号码:
SELECT id_no FROM student_ids
WHERE student_name IN ('Alice','Charlie','Bob');
为了简化服务器端处理,我想按照与学生姓名相同的顺序对结果集进行排序。换句话说,无论表的实际排序或任何特定供应商的实现行为如何,结果集都将为{alice_id_no, charlie_id_no, bob_id_no}
。
我能想到的唯一解决方案是:
. . .
ORDER BY
CASE WHEN student_name='Alice' THEN 0
WHEN student_name='Charlie' THEN 1
WHEN student_name='Bob' THEN 2 END;
但在尝试动态生成/运行此查询时,这似乎非常麻烦和麻烦。
有更好的方法吗?
更新我通过预先排序学生的名字给出了一个可怕的例子。我改变名称是故意不分类的。换句话说,我想以非ASC或DESC友好的方式对名称进行排序。
更新II Oracle,但出于知识的考虑,我也在寻找更一般的解决方案。
答案 0 :(得分:1)
你能这样做吗?
order by student_name
要进行自定义排序,您只需要一个case
:
ORDER BY (CASE WHEN student_name = 'Alice' THEN 1
WHEN student_name = 'Bob' THEN 2
WHEN student_name = 'Charlie' THEN 3
ELSE 4
END)
答案 1 :(得分:1)
您为样本数据提供的ORDER BY
表达式相当于ORDER BY student_name
。那是你的意图吗?
如果你想要一个不按字母顺序排列的自定义排序,我想你可能有这样的意思:
ORDER BY
CASE
WHEN student_name = 'Alice' THEN 0
WHEN student_name = 'Charlie' THEN 1
WHEN student_name = 'Bob' THEN 2
END;
您也可以使用派生表,它包含名称以及您想要的顺序。这样你只需要在一个时间内输入名字:
SELECT S.id_no
FROM
student_ids AS S
INNER JOIN (
SELECT Name = 'Alice', Seq = 0 FROM DUAL
UNION ALL SELECT 'Bob', 2 FROM DUAL
UNION ALL SELECT 'Charlie', 1 FROM DUAL
) AS N
ON S.student_name = N.Name
ORDER BY
N.Seq;
您也可以将它们放入临时表中,但在Oracle中可能会有点痛苦。
答案 2 :(得分:0)
为什么不这样:
SELECT id_no FROM student_ids student_name IN('Alice','Bob','Charlie') ORDER BY student_name
答案 3 :(得分:0)
您可ORDER BY
列SELECT
列表或WHERE
条款中的所有列
SELECT id_no
FROM student_ids
WHERE student_name IN ('Alice','Bob','Charlie)
ORDER BY id_no;
答案 4 :(得分:0)
添加一个表来保存排序优先级,然后您可以在任何查询中使用sort_priorities(并轻松更新优先级):
CREATE TABLE student_name_sort_priorities (
student_name VARCHAR2(30) CONSTRAINT student_name_sort_priority__pk PRIMARY KEY,
sort_priority NUMBER(10) CONSTRAINT student_name_sort_priority__nn NOT NULL
CONSTRAINT student_name_sort_priority__u UNIQUE
);
(如果您希望对两个值进行等效排序,则不要包含UNIQUE
约束。)
INSERT INTO student_name_sort_priorities VALUES ( 'Alice', 0 );
INSERT INTO student_name_sort_priorities VALUES ( 'Charlie', 2 );
INSERT INTO student_name_sort_priorities VALUES ( 'Bob', 1 );
然后,您可以使用student_ids
表加入排序优先级表,并使用额外列来执行排序:
SELECT id_no
FROM student_ids s
LEFT OUTER JOIN
student_name_sort_priorities p
ON (s.student_name = p.student_name)
ORDER BY
sort_priority NULLS LAST;
我使用了LEFT OUTER JOIN
,因此如果student_name_sort_priorities
表中没有包含名称,则它不会限制查询返回的行;出于类似原因,在排序中使用NULLS LAST
- 任何不在排序优先级表中的学生姓名将返回NULL
排序优先级,并放置在排序结束时。如果您不想这样做,请使用INNER JOIN
并删除NULLS LAST
。
答案 5 :(得分:0)
如何使用'varchar'表类型,如下面的内置:
TYPE dbms_debug_vc2coll is table of varchar2(1000);
试验:
SQL> select customer_id, cust_first_name, cust_last_name from customers where cust_first_name in
2 (select column_value from table(sys.dbms_debug_vc2coll('Frederic','Markus','Dieter')));
CUSTOMER_ID CUST_FIRST_NAME CUST_LAST_NAME
----------- -------------------- --------------------
154 Frederic Grodin
149 Markus Rampling
152 Dieter Matthau
这似乎迫使订单,但这可能只是运气不好。我不是一个真正的SQL专家。 这个的执行计划使用'collection iterator'而不是典型的大'或':
select customer_id, cust_first_name, cust_last_name from customers where cust_first_name in ('Frederic','Markus','Dieter');
赫斯,海恩。