如何逐个写出正确的顺序
How to write a correct order by case
我有这个问题,如果我正常使用sql
语句,我的意思是这样的:
SELECT p.id_plecari, p.id_aeroport, p.id_clasa, p.id_avion, p.data, p.ora, c.pret, av.nume, a.Nume, a.Locatie
from plecari p, clasa c, avioane av, aeroport a
where
p.id_aeroport = a.id_aeroport
AND p.id_clasa = c.id_clasa
AND p.id_avion = av.id_avion
AND p.id_plecari not in(SELECT r.id_plecare from rezervari r WHERE r.id_client = idClient)
ORDER BY p.id_clasa ASC;
一切都如我所料,完美如 this picture
但是在我添加 CASE
语句的那一刻,一切都搞砸了:
BEGIN
SELECT p.id_plecari, p.id_aeroport, p.id_clasa, p.id_avion, p.data, p.ora, c.pret, av.nume, a.Nume, a.Locatie
from plecari p, clasa c, avioane av, aeroport a
where
p.id_aeroport = a.id_aeroport
AND p.id_clasa = c.id_clasa
AND p.id_avion = av.id_avion
AND p.id_plecari not in(SELECT r.id_plecare from rezervari r WHERE r.id_client = idClient) ORDER BY
(CASE
WHEN (orderby = 1 AND orderas = false) THEN p.id_plecari
WHEN (orderby = 2 AND orderas = false) THEN av.nume
END) ASC ,
(CASE
WHEN (orderby = 1 AND orderas = true) THEN p.id_plecari
WHEN (orderby = 2 AND orderas = true) THEN av.nume
END) DESC;
END
一切看起来 like this!
SELECT
p.id_plecari, p.id_aeroport, p.id_clasa, p.id_avion, p.data, p.ora, c.pret, av.nume, a.Nume, a.Locatie
FROM
plecari p
INNER JOIN
clasa c
ON p.id_clasa = c.id_clasa
INNER JOIN
avioane av
ON p.id_avion = av.id_avion
INNER JOIN
aeroport a
ON p.id_aeroport = a.id_aeroport
WHERE
p.id_plecari not in (
SELECT r.id_plecare from rezervari r WHERE r.id_client = idClient
)
ORDER BY
CASE WHEN (orderby = 1 AND orderas = false) THEN p.id_plecari END,
CASE WHEN (orderby = 2 AND orderas = false) THEN av.nume END,
CASE WHEN (orderby = 1 AND orderas = true ) THEN p.id_plecari END DESC,
CASE WHEN (orderby = 2 AND orderas = true ) THEN av.nume END DESC;
这说明了如何使用 JOIN
,以及如何将 ORDER BY
分成几部分。
但是请注意,这种“条件排序”样式的性能可能非常差。
这是因为数据库必须生成一个执行计划来满足所有可能性。
性能更高的方法是将主查询作为视图,然后有类似于...
IF (orderby = 1 AND orderas = false) THEN
SELECT * FROM yourView ORDER BY p.id_plecari;
ELSEIF (orderby = 2 AND orderas = false) THEN
SELECT * FROM yourView ORDER BY av.nume;
ELSEIF (orderby = 1 AND orderas = true) THEN
SELECT * FROM yourView ORDER BY p.id_plecari DESC;
ELSEIF (orderby = 2 AND orderas = true) THEN
SELECT * FROM yourView ORDER BY av.nume DESC;
ENDIF;
这允许每个排序模式有不同的执行计划。
- This 解释得更详细
我有这个问题,如果我正常使用sql
语句,我的意思是这样的:
SELECT p.id_plecari, p.id_aeroport, p.id_clasa, p.id_avion, p.data, p.ora, c.pret, av.nume, a.Nume, a.Locatie
from plecari p, clasa c, avioane av, aeroport a
where
p.id_aeroport = a.id_aeroport
AND p.id_clasa = c.id_clasa
AND p.id_avion = av.id_avion
AND p.id_plecari not in(SELECT r.id_plecare from rezervari r WHERE r.id_client = idClient)
ORDER BY p.id_clasa ASC;
一切都如我所料,完美如 this picture
但是在我添加 CASE
语句的那一刻,一切都搞砸了:
BEGIN
SELECT p.id_plecari, p.id_aeroport, p.id_clasa, p.id_avion, p.data, p.ora, c.pret, av.nume, a.Nume, a.Locatie
from plecari p, clasa c, avioane av, aeroport a
where
p.id_aeroport = a.id_aeroport
AND p.id_clasa = c.id_clasa
AND p.id_avion = av.id_avion
AND p.id_plecari not in(SELECT r.id_plecare from rezervari r WHERE r.id_client = idClient) ORDER BY
(CASE
WHEN (orderby = 1 AND orderas = false) THEN p.id_plecari
WHEN (orderby = 2 AND orderas = false) THEN av.nume
END) ASC ,
(CASE
WHEN (orderby = 1 AND orderas = true) THEN p.id_plecari
WHEN (orderby = 2 AND orderas = true) THEN av.nume
END) DESC;
END
一切看起来 like this!
SELECT
p.id_plecari, p.id_aeroport, p.id_clasa, p.id_avion, p.data, p.ora, c.pret, av.nume, a.Nume, a.Locatie
FROM
plecari p
INNER JOIN
clasa c
ON p.id_clasa = c.id_clasa
INNER JOIN
avioane av
ON p.id_avion = av.id_avion
INNER JOIN
aeroport a
ON p.id_aeroport = a.id_aeroport
WHERE
p.id_plecari not in (
SELECT r.id_plecare from rezervari r WHERE r.id_client = idClient
)
ORDER BY
CASE WHEN (orderby = 1 AND orderas = false) THEN p.id_plecari END,
CASE WHEN (orderby = 2 AND orderas = false) THEN av.nume END,
CASE WHEN (orderby = 1 AND orderas = true ) THEN p.id_plecari END DESC,
CASE WHEN (orderby = 2 AND orderas = true ) THEN av.nume END DESC;
这说明了如何使用 JOIN
,以及如何将 ORDER BY
分成几部分。
但是请注意,这种“条件排序”样式的性能可能非常差。
这是因为数据库必须生成一个执行计划来满足所有可能性。
性能更高的方法是将主查询作为视图,然后有类似于...
IF (orderby = 1 AND orderas = false) THEN
SELECT * FROM yourView ORDER BY p.id_plecari;
ELSEIF (orderby = 2 AND orderas = false) THEN
SELECT * FROM yourView ORDER BY av.nume;
ELSEIF (orderby = 1 AND orderas = true) THEN
SELECT * FROM yourView ORDER BY p.id_plecari DESC;
ELSEIF (orderby = 2 AND orderas = true) THEN
SELECT * FROM yourView ORDER BY av.nume DESC;
ENDIF;
这允许每个排序模式有不同的执行计划。
- This 解释得更详细