PLSQL:需要帮助来理解ORDER BY中的CASE指令

时间:2011-04-01 15:18:02

标签: oracle plsql case sql-order-by

我有一段代码,里面有一个带有CASE的ORDER BY:

                        ORDER BY
                        (
                            CASE
                                WHEN r.id BETWEEN 900 AND 999 THEN '1AAAAA'
                                ELSE '2'
                                    || upper(id.name)
                            END) ASC,
                        r.date DESC ;

有人可以解释一下:

  1. '1AAAAA'和'2'的含义是什么?
  2. 是什么意思
      

    ||上(id.name)

4 个答案:

答案 0 :(得分:3)

在PL / SQL中,||concatenation operator

排序的确切方式取决于查询的其余部分,但看起来它将r.id BETWEEN 900 AND 999的记录放在其他记录之前,这些记录按id.name排序。

答案 1 :(得分:3)

case表达式求值为

CASE
  WHEN r.id BETWEEN 900 AND 999 THEN '1AAAAA'
  ELSE '2'
    || upper(id.name)
END

以上整个代码块,根据r.id的值,评估为'1AAAAA'或'2 [value-of-r.id]'。

由于这是在order by子句中,因此该值将用于对结果进行排序,如下所示:

  1. 首先列出r.id介于900和999之间的所有记录
  2. 然后按r.id的升序列出所有其他记录(||是字符串连接运算符)。

答案 2 :(得分:1)

这是一些数据。正如您所看到的那样,名称按ASCII顺序排序,这与字母顺序不完全相同:

SQL> select id, name, somedate
  2  from t42
  3  order by name, somedate
  4  /

        ID NAME       SOMEDATE
---------- ---------- ---------
         8 Billington 24-MAR-11
        13 Cave       19-MAR-11
         4 Clarke     28-MAR-11
       919 Feuerstein 13-MAR-11
        16 Gasparotto 16-MAR-11
      1014 KULASH     18-MAR-11
         1 Kestelyn   31-MAR-11
       917 Kishore    15-MAR-11
         2 Lira       30-MAR-11
         6 PADFIELD   26-MAR-11
        11 Rigby      21-MAR-11
      1007 Robertson  25-MAR-11
        12 SCHNEIDER  20-MAR-11
         9 SPENCER    23-MAR-11
         3 TRICHLER   29-MAR-11
       918 VERREYNNE  14-MAR-11
        10 boehmer    22-MAR-11
        15 hall       17-MAR-11
       920 poder      12-MAR-11
         5 van wijk   27-MAR-11
      1021            11-MAR-11

21 rows selected.

SQL>

upper(name)排序会使其不区分大小写:

SQL> select id, name, somedate
  2  from t42
  3  order by upper(name), somedate
  4  /

        ID NAME       SOMEDATE
---------- ---------- ---------
         8 Billington 24-MAR-11
        10 boehmer    22-MAR-11
        13 Cave       19-MAR-11
         4 Clarke     28-MAR-11
       919 Feuerstein 13-MAR-11
        16 Gasparotto 16-MAR-11
        15 hall       17-MAR-11
         1 Kestelyn   31-MAR-11
       917 Kishore    15-MAR-11
      1014 KULASH     18-MAR-11
         2 Lira       30-MAR-11
         6 PADFIELD   26-MAR-11
       920 poder      12-MAR-11
        11 Rigby      21-MAR-11
      1007 Robertson  25-MAR-11
        12 SCHNEIDER  20-MAR-11
         9 SPENCER    23-MAR-11
         3 TRICHLER   29-MAR-11
         5 van wijk   27-MAR-11
       918 VERREYNNE  14-MAR-11
      1021            11-MAR-11

21 rows selected.

SQL>

CASE()通过先对指定ID范围内的所有记录进行分组,然后对所有其他记录进行分组,进一步改变这一点。所选范围内的记录仅按日期排序,而其他记录仍按名称排序,然后按日期排序:

SQL> select id, name, somedate
  2  from t42
  3          ORDER BY
  4          (
  5              CASE
  6                  WHEN id BETWEEN 900 AND 999 THEN '1AAAAA'
  7                  ELSE '2'
  8                      || upper(name)
  9              END) ASC,
 10          somedate DESC
 11  /

        ID NAME       SOMEDATE
---------- ---------- ---------
       917 Kishore    15-MAR-11
       918 VERREYNNE  14-MAR-11
       919 Feuerstein 13-MAR-11
       920 poder      12-MAR-11
      1021            11-MAR-11
         8 Billington 24-MAR-11
        10 boehmer    22-MAR-11
        13 Cave       19-MAR-11
         4 Clarke     28-MAR-11
        16 Gasparotto 16-MAR-11
        15 hall       17-MAR-11
         1 Kestelyn   31-MAR-11
      1014 KULASH     18-MAR-11
         2 Lira       30-MAR-11
         6 PADFIELD   26-MAR-11
        11 Rigby      21-MAR-11
      1007 Robertson  25-MAR-11
        12 SCHNEIDER  20-MAR-11
         9 SPENCER    23-MAR-11
         3 TRICHLER   29-MAR-11
         5 van wijk   27-MAR-11

21 rows selected.

SQL>

答案 3 :(得分:0)

1.'AAAAAA'和'2'的含义是什么?

这是字面常量。

2. ||是什么意思上(id.name)

||是SQL标准连接运算符。 'A'|| 'B'产生'AB'。

恕我直言,你的问题是整个order by case意味着什么,所以,一步一步走:

             ORDER BY
                    (
                        CASE
                            WHEN r.id BETWEEN 900 AND 999 THEN '1AAAAA'
                            ELSE '2'
                                || upper(id.name)
                        END) ASC,
                    r.date DESC ;

这将根据案例表达式评估(上升)的结果,然后通过r.date(后代)对结果集进行排序。

案件只会返回'1AAAAA'以获取900到999之间的任何ID(这将由r.date订购,记得吗?'

对于任何其他值,它将在id.name之前连接2。

这可确保任何ID在900和999之间的记录出现在第一个“组”中,该组按日期排序,降序排列。然后第二组将包含所有其他记录,按名称的上部排序,然后按日期排序。

您可能希望查看此数据以了解其工作原理...只需将case表达式作为新列添加到select语句中。

例如,如果您的查询开头如下:

SELECT r.id, id.name
  FROM

添加如下情况:

SELECT r.id, id.name
       , 
       CASE
         WHEN r.id BETWEEN 900 AND 999 THEN '1AAAAA'
         ELSE '2'|| upper(id.name)
       END ORDER_CRITERIA
  FROM

这将帮助您了解该表达式的内容,因为您会将生成的数据视为查询的最后一列。