Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Làm thế nào tôi có thể tìm thấy hộp có kích thước phù hợp cho từng sản phẩm?

Chìa khóa, tất nhiên, là sự kết hợp giữa hai bảng. Tôi hiển thị nó một cách riêng biệt trước tiên, thay vì truy vấn hoàn chỉnh, để giúp hiểu rõ. Đối với mỗi mặt hàng, chúng tôi tìm thấy TẤT CẢ các kích thước hộp có thể chứa mặt hàng đó.

Trong mọi trường hợp, có thể so khớp nếu chiều cao sản phẩm <=chiều cao hộp và hai kích thước còn lại phù hợp, theo một trong hai hoán vị (sản phẩm luôn có thể được xoay để vừa với hộp, cho dù chúng có thể xếp được hay không).

Chỉ đối với những sản phẩm có thể xếp được, chúng tôi được phép xoay sản phẩm theo cả ba chiều để vừa với chúng trong hộp. Điều này có nghĩa là, chỉ đối với các sản phẩm có thể xếp lớp, chúng tôi có thể so sánh chiều rộng hoặc chiều sâu của sản phẩm với chiều cao của hộp và so sánh hai kích thước còn lại của sản phẩm với chiều rộng và chiều sâu của hộp.

Khi chúng tôi hiểu những gì tôi vừa nói (như cách chúng tôi sẽ làm điều này mà không cần máy tính, chỉ với bút chì trên giấy), việc dịch sang mã gần như tự động:

select p.id, b.box_size
from   products p left outer join boxes b
       on
            p.h <= b.h and least   (p.w, p.d) <= least   (b.w, b.d)
                       and greatest(p.w, p.d) <= greatest(b.w, b.d)
       or
       p.layable = 'y'
          and
          ( p.w <= b.h and least   (p.h, p.d) <= least   (b.w, b.d)
                       and greatest(p.h, p.d) <= greatest(b.w, b.d)
            or
            p.d <= b.h and least   (p.w, p.h) <= least   (b.w, b.d)
                       and greatest(p.w, p.h) <= greatest(b.w, b.d)
          )
;

Đầu ra:

ID  BOX_SIZE
--- --------
a   S       
a   M       
a   L       
b   M       
b   L       
c   L       
d   S       
d   M       
d   L       
e   L       
f   L       
g   S       
g   M       
g   L       
h   M       
h   L       
i   L       
j      

Đối với mỗi sản phẩm, chúng tôi tìm thấy TẤT CẢ các kích thước phù hợp.

Lưu ý phần nối bên ngoài trong truy vấn, để bao gồm các sản phẩm không vừa với BẤT KỲ kích thước hộp nào; đó là trường hợp của sản phẩm j , xuất hiện ở cuối đầu ra. Lưu ý rằng tôi sử dụng null làm điểm đánh dấu cho " không khả dụng "- các từ" không có sẵn "không thêm thông tin có giá trị khi sử dụng null đơn giản .

Bước tiếp theo là một tổng hợp đơn giản - đối với mỗi sản phẩm, hãy tìm kích thước nhỏ nhất phù hợp. Công cụ tốt nhất cho việc này là FIRST hàm tổng hợp (như được sử dụng bên dưới). Chúng tôi phải đặt hàng theo kích thước hộp; vì các kích thước là S, M, L (ngẫu nhiên theo thứ tự bảng chữ cái ngược lại), tôi sử dụng decode() hàm gán 1 cho S, 2 cho M, 3 cho L. Truy vấn tổng hợp tìm kích thước "đầu tiên" phù hợp với từng sản phẩm.

Điều quan trọng ở đây là truy vấn có thể được tổng quát hóa một cách dễ dàng thành bất kỳ số lượng "kích thước hộp" nào có thể - ngay cả khi không phải cả ba kích thước đều theo thứ tự tăng dần. (Bạn cũng có thể có các hộp chỉ có một trong các kích thước rất lớn trong khi các kích thước khác rất nhỏ, v.v.). Bạn có thể đặt hàng theo khối lượng hộp hoặc bạn có thể lưu trữ trong bảng hộp một thứ tự ưu tiên, tương đương với những gì tôi thực hiện trong truy vấn với decode() chức năng.

Cuối cùng, truy vấn và đầu ra trông như thế này. Lưu ý rằng tôi đã sử dụng nvl() trong select mệnh đề tạo 'not available' cho mục cuối cùng, trong trường hợp bạn thực sự cần nó (tôi nghi ngờ, nhưng đó không phải là vấn đề kinh doanh của tôi.)

select p.id, 
       nvl(  min(b.box_size) keep (dense_rank first 
             order by decode(b.box_size, 'S', 1, 'M', 2, 'L', 3))
          , 'not available') as box_size
from   products p left outer join boxes b
       on
            p.h <= b.h and least   (p.w, p.d) <= least   (b.w, b.d)
                       and greatest(p.w, p.d) <= greatest(b.w, b.d)
       or
       p.layable = 'y'
          and
          ( p.w <= b.h and least   (p.h, p.d) <= least   (b.w, b.d)
                       and greatest(p.h, p.d) <= greatest(b.w, b.d)
            or
            p.d <= b.h and least   (p.w, p.h) <= least   (b.w, b.d)
                       and greatest(p.w, p.h) <= greatest(b.w, b.d)
          )
group  by p.id
;

ID  BOX_SIZE
--- --------
a   S       
b   M       
c   L       
d   S       
e   L       
f   L       
g   S       
h   M       
i   L       
j   not available   


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Dữ liệu được nhóm theo ngày trong oracle sql

  2. Cách sử dụng AddBatch / withBatch đúng cách để chèn hàng loạt giá trị thẻ xml vào bảng cơ sở dữ liệu

  3. Cách sử dụng hàm Coalesce trong Oracle

  4. Tôi nên sử dụng loại trình điều khiển JDBC nào để truy cập Cơ sở dữ liệu Oracle?

  5. Không thể chạy truy vấn động trong thủ tục được lưu trữ trong khi chọn số lượng bản ghi