Home > Back-end >  Why do my two queries give the same results but in a different order?
Why do my two queries give the same results but in a different order?

Time:04-10

The following two queries give the same results, except in a different order.

select pack_id ,speed , monthly_payment
from   acdb_packages 
where  monthly_payment > all(select monthly_payment from acdb_packages where speed = '5Mbps');
select p1.pack_id, p1.speed, p1.monthly_payment
from   acdb_packages p1
where  p1.monthly_payment > (select max(monthly_payment) from acdb_packages p2 where p2.speed ='5Mbps');

To change the first query by using max instead of ALL, I wrote the second query. The result shows both of them with same number of rows. But the difference is the order.

The result shows that the order of the first one is monthly_payment asc, while the order of the econd one is pact_id asc. Is there any problem with in the second query? I also want same order.

CodePudding user response:

If you want a ordered result you need to add an ORDER BY clause. Otherwise your result is in "random" sort order. There are some rules that autosort your result but it's bad practice to hope the sql engine sorts things if you do not specify that you want a sorted result.

So you could just add at the end ORDER BY 3 which is short for order the result by the 3rd result column or better add ORDER BY monthly_payment

CodePudding user response:

If you want the results of a query to display in a specific order then you need to use an ORDER BY clause. Relational DBMSs have no built-in record order and the order of records is random - they are normally returned in PK order but this should not be assumed or relied upon

CodePudding user response:

I created a test table with an index on monthly_payment, and checked the execution plans for both queries. The > all version used full scans, and so returned results in the order they happened to be found in storage, and the = max version used the index, and so returned the results in the order they were returned by the index-driven nested-loop operation, meaning the order in which the values of monthly_payment are held in the index.

create table acdb_packages
( pack_id            number constraint acdb_packages_pk primary key
, monthly_payment    number not null
, speed              varchar2(10) not null );

insert all
    into acdb_packages (pack_id, monthly_payment, speed) values ( 1, 90, '200Mbps')
    into acdb_packages (pack_id, monthly_payment, speed) values ( 2, 80, '175Mbps')
    into acdb_packages (pack_id, monthly_payment, speed) values ( 3, 70, '150Mbps')
    into acdb_packages (pack_id, monthly_payment, speed) values ( 4, 60, '100Mbps')
    into acdb_packages (pack_id, monthly_payment, speed) values ( 5, 70, '10Mbps')
    into acdb_packages (pack_id, monthly_payment, speed) values ( 6, 60, '5Mbps')
    into acdb_packages (pack_id, monthly_payment, speed) values ( 7, 50, '4Mbps')
    into acdb_packages (pack_id, monthly_payment, speed) values ( 8, 70, '20Mbps')
    into acdb_packages (pack_id, monthly_payment, speed) values ( 9, 60, '5Mbps')
    into acdb_packages (pack_id, monthly_payment, speed) values (10, 50, '4Mbps')
select * from dual;

create index acdb_packages_monthly_payment_ix on acdb_packages (monthly_payment);

First query:

select pack_id, speed, monthly_payment
from   acdb_packages
where  monthly_payment > all(select monthly_payment from acdb_packages where speed = '5Mbps');

   PACK_ID SPEED      MONTHLY_PAYMENT
---------- ---------- ---------------
         1 200Mbps                 90
         2 175Mbps                 80
         3 150Mbps                 70
         5 10Mbps                  70
         8 20Mbps                  70

5 rows selected.


Plan hash value: 2904906835

--------------------------------------------------------------------------------------------
| Id  | Operation                  | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT           |               |     1 |    23 |     4   (0)| 00:00:01 |
|   1 |  NESTED LOOPS ANTI         |               |     1 |    23 |     4   (0)| 00:00:01 |
|   2 |   TABLE ACCESS STORAGE FULL| ACDB_PACKAGES |    10 |   130 |     2   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS STORAGE FULL| ACDB_PACKAGES |     2 |    20 |     0   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   3 - storage("SPEED"='5Mbps' AND "MONTHLY_PAYMENT"<="MONTHLY_PAYMENT")
       filter("SPEED"='5Mbps' AND "MONTHLY_PAYMENT"<="MONTHLY_PAYMENT")

Second query:

select pack_id, speed, monthly_payment
from   acdb_packages
where  monthly_payment > (select max(monthly_payment) from acdb_packages p2 where p2.speed ='5Mbps');

   PACK_ID SPEED      MONTHLY_PAYMENT
---------- ---------- ---------------
         3 150Mbps                 70
         5 10Mbps                  70
         8 20Mbps                  70
         1 200Mbps                 90
         2 175Mbps                 80

5 rows selected.


Plan hash value: 1313930309

------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name                             | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |                                  |     1 |    13 |     3   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| ACDB_PACKAGES                    |     1 |    13 |     1   (0)| 00:00:01 |
|   2 |   SORT CLUSTER BY ROWID BATCHED     |                                  |     1 |       |     1   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN                 | ACDB_PACKAGES_MONTHLY_PAYMENT_IX |     1 |       |     1   (0)| 00:00:01 |
|   4 |     SORT AGGREGATE                  |                                  |     1 |    10 |            |          |
|*  5 |      TABLE ACCESS STORAGE FULL      | ACDB_PACKAGES                    |     2 |    20 |     2   (0)| 00:00:01 |
------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   3 - access("P1"."MONTHLY_PAYMENT"> (SELECT MAX("MONTHLY_PAYMENT") FROM "ACDB_PACKAGES" "P2" WHERE
              "P2"."SPEED"='5Mbps'))
   5 - storage("P2"."SPEED"='5Mbps')
       filter("P2"."SPEED"='5Mbps')
  • Related