简体   繁体   中英

Oracle - where the orderly column ID e.g. ORDER BY 1 is allwed?

Question

What are the rules where the orderly column ID 1, 2, ... is allowed? From which part of document can I tell?

SELECT *
FROM (
    SELECT Months * Salary, COUNT(*)
    FROM Employee
    GROUP BY (Months * Salary) 
    ORDER BY 1 DESC     <---- This is OK
    )
WHERE ROWNUM = 1;

----------
108064 7
SELECT *
FROM (
    SELECT Months * Salary, COUNT(*)
    FROM Employee
    GROUP BY 1        <--- ORA-00979: not a GROUP BY expression
    ORDER BY 1 DESC
    )
WHERE ROWNUM = 1;

----------
SELECT Months * Salary, COUNT(*)
*
ERROR at line 3:
ORA-00979: not a GROUP BY expression

For this case, which document can tell it is not allowed and why?

在此处输入图像描述

在此处输入图像描述

  • In the GROUP BY clause the 1 is a number literal value.
  • In the ORDER BY clause the 1 refers to the the first term of the SELECT clause.

If you do:

SELECT *
FROM (
    SELECT COUNT(*)
    FROM Employee
    GROUP BY 1              -- A number literal
    ORDER BY 1 DESC
    )
WHERE ROWNUM = 1;

It is the same as:

SELECT *
FROM (
    SELECT COUNT(*)
    FROM Employee
    GROUP BY NULL           -- A NULL literal
    ORDER BY 1 DESC
    )
WHERE ROWNUM = 1;

or

SELECT *
FROM (
    SELECT COUNT(*)
    FROM Employee
    GROUP BY 'ABC'          -- A string literal
    ORDER BY 1 DESC
    )
WHERE ROWNUM = 1;

However,

SELECT *
FROM (
    SELECT Months * Salary, COUNT(*)
    FROM Employee
    GROUP BY 1
    ORDER BY 1 DESC
    )
WHERE ROWNUM = 1;

Is not valid as 1 is a literal number value that you are grouping by whereas Months and Salary are column names that are in a GROUP BY query but are not aggregated.

In the images only in order-by you can find the "position" option. Also, from "Java DB Technical Documentation":

GROUP BY 
{
    column-Name [ , column-Name ]*  
|
    ROLLUP ( column-Name [ , column-Name ]* )
}
column-Name must be a column from the current scope of the query;
there can be no columns from a query block outside the current scope.
For example, if a GROUP BY clause is in a subquery,
it cannot refer to columns in the outer query.

ORDER BY { column-Name | ColumnPosition | Expression }
    [ ASC | DESC ]
    [ NULLS FIRST | NULLS LAST ]
    [ , column-Name | ColumnPosition | Expression 
    [ ASC | DESC ]
    [ NULLS FIRST | NULLS LAST ]
    ] * 

ColumnPosition
An integer that identifies the number of the column in the SelectItems
in the underlying query of the SELECT statement.
ColumnPosition must be greater than 0 and not greater
than the number of columns in the result table. In other words,
if you want to order by a column, that column must be specified
in the SELECT list.

Positional integer column ID is available in ORDER BY but not in GROUP BY.

Positional ORDER BY notation

position

Specify position to order rows based on their value for the expression in this position of the select list. The position value must be an integer .

You can specify multiple expressions in the order_by_clause. Oracle Database first sorts rows based on their values for the first expression. Rows with the same value for the first expression are then sorted based on their values for the second expression, and so on. The database sorts nulls following all others in ascending order and preceding all others in descending order. Refer to "Sorting Query Results" for a discussion of ordering query results.

To select the same information as the previous SELECT and use the positional ORDER BY notation, issue the following statement, which orders by ascending department_id, then descending salary, and finally alphabetically by last_name:

SELECT last_name, department_id, salary 
   FROM employees 
   ORDER BY 2 ASC, 3 DESC, 1; 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM