I have a SQL query that works fine in SQL Server, but it does not work on Oracle and, in my opinion, it should not.
This is an example to reproduce it:
CREATE TABLE TEST
( TEST_ID NUMBER(37,0) NOT NULL,
TEST_NAME VARCHAR2(50 BYTE),
TEST_GROUP VARCHAR2(20 BYTE),
CONSTRAINT TEST_PK PRIMARY KEY (TEST_ID) );
INSERT INTO TEST (TEST_ID, TEST_NAME) VALUES (1, 'TEST 1');
INSERT INTO TEST (TEST_ID, TEST_NAME, TEST_GROUP) VALUES (2, 'TEST 2', 'A');
INSERT INTO TEST (TEST_ID, TEST_NAME, TEST_GROUP) VALUES (3, 'TEST 3', 'B');
INSERT INTO TEST (TEST_ID, TEST_NAME, TEST_GROUP) VALUES (4, 'TEST 4', 'A');
This query returns the expected information:
SELECT TEST_GROUP, COUNT(R$), MIN(R$) R$_A, MAX(R$) R$_Z
FROM (
SELECT MAIN.*, ROW_NUMBER() OVER (ORDER BY TEST_GROUP, TEST_ID) R$
FROM ( SELECT TEST_ID, TEST_NAME, TEST_GROUP
FROM TEST
GROUP BY TEST_ID, TEST_NAME, TEST_GROUP
) MAIN
) MAIN
GROUP BY TEST_GROUP
It returns three TEST_GROUPS with the correct calculations.
TEST_GROUP COUNT(R$) R$_A R$_Z
-------------- --------- ------- -------
A 2 1 2
B 1 3 3
(null) 1 4 4
Explain the plan:
OPERATION OBJECT_NAME CARDINALITY COST
SELECT STATEMENT 4 3
SORT (GROUP BY NOSORT) 4 3
VIEW 4 3
WINDOW (NOSORT) 4 3
SORT (GROUP BY) 4 3
TABLE ACCESS (FULL) TEST 4 3
Other XML
{info}
info type="db_version"
12.1.0.1
info type="parse_schema"
"BABTEC"
info type="dynamic_sampling"
2
info type="plan_hash"
1486410247
info type="plan_hash_2"
1249517352
{hint}
FULL(@"SEL$335DD26A" "TEST"@"SEL$3")
NO_ACCESS(@"SEL$1" "MAIN"@"SEL$1")
OUTLINE(@"SEL$3")
OUTLINE(@"SEL$2")
OUTLINE_LEAF(@"SEL$1")
MERGE(@"SEL$3")
OUTLINE_LEAF(@"SEL$335DD26A")
ALL_ROWS
DB_VERSION('12.1.0.1')
OPTIMIZER_FEATURES_ENABLE('12.1.0.1')
IGNORE_OPTIM_EMBEDDED_HINTS
But if we change the sorting to ROW_NUMBER
(changing the value from the default ASC to DESC), it will not:
SELECT TEST_GROUP, COUNT(R$), MIN(R$) R$_A, MAX(R$) R$_Z
FROM (
SELECT MAIN.*, ROW_NUMBER() OVER (ORDER BY TEST_GROUP **DESC**, TEST_ID) R$
FROM ( SELECT TEST_ID, TEST_NAME, TEST_GROUP
FROM TEST
GROUP BY TEST_ID, TEST_NAME, TEST_GROUP
) MAIN
) MAIN
GROUP BY TEST_GROUP;
It returns only one group.
TEST_GROUP COUNT(R$) R$_A R$_Z
-------------- --------- ------- -------
A 4 1 4
Explain the plan:
OPERATION OBJECT_NAME CARDINALITY COST
SELECT STATEMENT 4 3
HASH(GROUP BY) 4 3
VIEW 4 3
WINDOW (NOSORT) 4 3
SORT (GROUP BY) 4 3
TABLE ACCESS (FULL) TEST 4 3
Other XML
{info}
info type="db_version"
12.1.0.1
info type="parse_schema"
"BABTEC"
info type="dynamic_sampling"
2
info type="plan_hash"
1128091058
info type="plan_hash_2"
3776505473
{hint}
FULL(@"SEL$335DD26A" "TEST"@"SEL$3")
NO_ACCESS(@"SEL$1" "MAIN"@"SEL$1")
OUTLINE(@"SEL$3")
OUTLINE(@"SEL$2")
OUTLINE_LEAF(@"SEL$1")
MERGE(@"SEL$3")
OUTLINE_LEAF(@"SEL$335DD26A")
ALL_ROWS
DB_VERSION('12.1.0.1')
OPTIMIZER_FEATURES_ENABLE('12.1.0.1')
IGNORE_OPTIM_EMBEDDED_HINTS
Note that reproducing the problem requires that the most internal query has an expression GROUP BY
. If not, the result will be the one we expect:
SELECT TEST_GROUP, COUNT(R$), MIN(R$) R$_A, MAX(R$) R$_Z
FROM (
SELECT MAIN.*, ROW_NUMBER() OVER (ORDER BY TEST_GROUP DESC, TEST_ID) R$
FROM ( SELECT TEST_ID, TEST_NAME, TEST_GROUP
FROM TEST ) MAIN
) MAIN
GROUP BY TEST_GROUP;
TEST_GROUP COUNT(R$) R$_A R$_Z
(null) 1 1 1
B 1 2 2
A 2 3 4
We use Oracle Database 12c Release 12.1.0.1.0 - 64bit
, ORDER BY
GROUP BY, Oracle, SQLServer. :
SELECT TEST_GROUP, COUNT(R$), MIN(R$) R$_A, MAX(R$) R$_Z
FROM (
SELECT MAIN.*, ROW_NUMBER() OVER (ORDER BY TEST_GROUP DESC, TEST_ID) R$
FROM ( SELECT TEST_ID, TEST_NAME, TEST_GROUP
FROM TEST
GROUP BY TEST_ID, TEST_NAME, TEST_GROUP
ORDER BY TEST_GROUP DESC ) MAIN
) MAIN
GROUP BY TEST_GROUP;
TEST_GROUP COUNT(R$) R$_A R$_Z
(null) 1 1 1
B 1 2 2
A 2 3 4