Không, không có cách nào khác ngoài việc sử dụng kết nối với bảng thứ hai của bạn. Chắc chắn, bạn có thể viết truy vấn con vô hướng trong mệnh đề lựa chọn của bạn, hoặc bạn có thể viết hàm riêng của bạn, nhưng đó sẽ là thực hành không hiệu quả.
Nếu bạn cần dữ liệu từ bảng, bạn cần chọn từ đó.
EDIT: Tôi phải tinh chỉnh tuyên bố trước đó của mình về thực tiễn không hiệu quả.
Khi sử dụng truy vấn phụ vô hướng trong danh sách lựa chọn của bạn, bạn mong đợi rằng bạn đang buộc một kế hoạch giống như vòng lặp lồng nhau, nơi truy vấn con vô hướng được thực thi cho mỗi hàng của states_table. Ít nhất tôi mong rằng :-).
Tuy nhiên, Oracle đã triển khai bộ nhớ đệm truy vấn phụ vô hướng, dẫn đến tối ưu hóa thực sự tốt đẹp. Nó chỉ thực hiện truy vấn con 3 lần. Có một bài viết tuyệt vời về truy vấn phụ vô hướng nơi bạn có thể thấy rằng nhiều yếu tố đóng vai trò trong cách tối ưu hóa này hoạt động: http://www.oratechinfo.co.uk/scalar_subqueries.html#scalar3
Đây là thử nghiệm riêng của tôi để xem công việc này. Đối với một mô phỏng của bảng của bạn, tôi đã sử dụng kịch bản này:
create table states_table (id,state,filler)
as
select level
, floor(dbms_random.value(0,3))
, lpad('*',1000,'*')
from dual
connect by level <= 100000
/
alter table states_table add primary key (id)
/
create table lookup_table (state_num,state_desc)
as
select 0, 'initial' from dual union all
select 1, 'current' from dual union all
select 2, 'final' from dual
/
alter table lookup_table add primary key (state_num)
/
alter table states_table add foreign key (state) references lookup_table(state_num)
/
exec dbms_stats.gather_table_stats(user,'states_table',cascade=>true)
exec dbms_stats.gather_table_stats(user,'lookup_table',cascade=>true)
Sau đó, thực hiện truy vấn và có một cái nhìn tại các kế hoạch thực hiện thực:
SQL> select /*+ gather_plan_statistics */
2 s.id
3 , s.state
4 , l.state_desc
5 from states_table s
6 join lookup_table l on s.state = l.state_num
7/
ID STATE STATE_D
---------- ---------- -------
1 2 final
...
100000 0 initial
100000 rows selected.
SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'))
2/
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------
SQL_ID f6p6ku8g8k95w, child number 0
-------------------------------------
select /*+ gather_plan_statistics */ s.id , s.state , l.state_desc from states_table s join
lookup_table l on s.state = l.state_num
Plan hash value: 1348290364
---------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads | OMem | 1Mem | Used-Mem |
---------------------------------------------------------------------------------------------------------------------------------
|* 1 | HASH JOIN | | 1 | 99614 | 100K|00:00:00.50 | 20015 | 7478 | 1179K| 1179K| 578K (0)|
| 2 | TABLE ACCESS FULL| LOOKUP_TABLE | 1 | 3 | 3 |00:00:00.01 | 3 | 0 | | | |
| 3 | TABLE ACCESS FULL| STATES_TABLE | 1 | 99614 | 100K|00:00:00.30 | 20012 | 7478 | | | |
---------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("S"."STATE"="L"."STATE_NUM")
20 rows selected.
Bây giờ làm tương tự cho các biến thể subquery vô hướng:
SQL> select /*+ gather_plan_statistics */
2 s.id
3 , s.state
4 , (select l.state_desc
5 from lookup_table l
6 where l.state_num = s.state
7 )
8 from states_table s
9/
ID STATE (SELECT
---------- ---------- -------
1 2 final
...
100000 0 initial
100000 rows selected.
SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'))
2/
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------
SQL_ID 22y3dxukrqysh, child number 0
-------------------------------------
select /*+ gather_plan_statistics */ s.id , s.state , (select l.state_desc
from lookup_table l where l.state_num = s.state ) from states_table s
Plan hash value: 2600781440
---------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
---------------------------------------------------------------------------------------------------------------
| 1 | TABLE ACCESS BY INDEX ROWID| LOOKUP_TABLE | 3 | 1 | 3 |00:00:00.01 | 5 | 0 |
|* 2 | INDEX UNIQUE SCAN | SYS_C0040786 | 3 | 1 | 3 |00:00:00.01 | 2 | 0 |
| 3 | TABLE ACCESS FULL | STATES_TABLE | 1 | 99614 | 100K|00:00:00.30 | 20012 | 9367 |
---------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("L"."STATE_NUM"=:B1)
20 rows selected.
Và xem cột Bắt đầu ở bước 1 và 2: chỉ 3!
Cho dù tối ưu hóa này luôn là điều tốt trong tình huống của bạn, phụ thuộc vào nhiều yếu tố. Bạn có thể tham khảo bài viết đã đề cập trước đó để xem hiệu quả của một số bài viết.
Trong trường hợp của bạn chỉ với ba trạng thái, có vẻ như bạn không thể làm sai với biến thể truy vấn phụ vô hướng.
Trân trọng, Rob.
Đúng, có thể. Nhưng không thể. Tôi sẽ reword câu trả lời của tôi mặc dù :-) –
Điều này sẽ chỉ làm điều đó. Tôi không quá quen thuộc với sự cân bằng của thực tế này, nhưng nếu một truy vấn nhỏ tôi đang đối phó với nơi mà một giải mã lớn sẽ làm cho nó rất lộn xộn: (@ammoQ, bạn sẽ có một gợi ý cho một giá trị mặc định? Chúc mừng! – filippo
EDIT : nhiều hơn một chút để cung cấp một giá trị mặc định –