Tính tỷ lệ phần trăm của một hàng trên tổng tiền


13

Xin lỗi vì tiêu đề xấu, tôi không chắc đâu là tiêu đề tốt cho việc này.

Đây hiện là (chế độ xem đơn giản hóa) dữ liệu tôi đang làm việc với

Agent    |  Commission     
---------|------------
Smith    |    100
Neo      |    200
Morpheus |    300

Tôi cần tính tỷ lệ phần trăm của tổng hoa hồng, mỗi đại lý chịu trách nhiệm.

Vì vậy, đối với Đặc vụ Smith, Tỷ lệ phần trăm sẽ được tính là (Agent Smith's commission / Sum(commission)*100

Vì vậy, dữ liệu dự kiến ​​của tôi sẽ là

Agent    |  Commission   |  % Commission    
---------|---------------|---------------
Smith    |    100        |     17
Neo      |    200        |     33
Morpheus |    300        |     50

Tôi có một chức năng trả lại hoa hồng cho mỗi đại lý. Tôi có một chức năng khác trả về tỷ lệ phần trăm là (Commission/Sum(Commission))*100. Vấn đề là Sum(commission)được tính toán cho từng hàng và do truy vấn này sẽ được chạy trên Kho dữ liệu, bộ dữ liệu sẽ khá lớn (hiện tại, nó chỉ dưới 2000 bản ghi) và khá trung thực, một cách tiếp cận tồi (IMO ).

Có cách nào để Sum(Commission)không tính toán cho mỗi hàng được tìm nạp không?

Tôi đã suy nghĩ điều gì đó trên các dòng của truy vấn 2 phần, phần đầu tiên sẽ tìm nạp sum(commission)vào một biến / loại gói và phần thứ hai sẽ đề cập đến giá trị được tính toán trước này, nhưng tôi không chắc làm thế nào tôi có thể thực hiện được điều này.

Tôi bị giới hạn sử dụng SQL và tôi đang chạy trên Oracle 10g R2.


Rõ ràng không phải là một câu hỏi DBA (có lẽ nếu đó là không gian bảng chứ không phải nhân viên bán hàng?) - có lẽ nên có trên Stack Overflow.
Gaius

Câu trả lời:


23

Bạn đang tìm tỷ analytical function lệ_to numport

select 
  agent,
  round(ratio_to_report(commission) over ()*100) "% Comm."
from  
  commissions;

Tuyệt vời, không biết về điều này, cảm ơn!
Sathyajith Bhat

9

Để trả về tất cả các đại lý với tỷ lệ hoa hồng và tỷ lệ hoa hồng của họ, hãy sử dụng hàm phân tích không có mệnh đề phân tích để phân vùng nằm trên toàn bộ bảng:

SELECT Agent, commission, 100* commission / (SUM(commission) OVER ()) "% Commission" 
FROM commissions;

Như tôi đã học được từ René Nyffalanger (+1), hàm ratio_to_Vport thắt chặt cú pháp này.

Sử dụng gói để lưu trữ Ủy ban SUM sẽ liên quan đến PL / SQL, mà bạn đã loại trừ một cách cụ thể bằng cách chỉ ra rằng bạn muốn có giải pháp SQL, nhưng vì bạn đã sử dụng các hàm nên tôi cho rằng ý định của bạn không loại trừ PL / SQL. Nếu đây là trường hợp, thì giải pháp gói có thể giúp đỡ, nhưng nó phụ thuộc vào cách ứng dụng của bạn hoạt động.

Khi phiên của bạn được tạo lần đầu tiên và gọi hàm trong gói để nhận hoa hồng, có một cuộc gọi ngầm đến hàm tạo gói có thể lấy tổng và lưu trữ. Sau đó, bạn có thể tham chiếu số tiền được lưu trữ trong chức năng nhận hoa hồng của mình và nó sẽ chỉ phải thực hiện số tiền một lần. Tất nhiên ngay khi bạn gọi hàm từ một phiên khác, tổng sẽ được tính lại. Ngoài ra, việc gọi hàm cho mọi tác nhân sẽ kém hiệu quả hơn đáng kể so với việc gọi một câu lệnh SQL cho tất cả các tác nhân nếu ứng dụng của bạn có thể được thiết kế theo cách đó.

Bạn có thể muốn xem xét biến chức năng của mình thành một thủ tục trả về một con trỏ cho truy vấn ở trên hoặc có thể có một hàm trả về kết quả của truy vấn dưới dạng tập kết quả được đặt.

Dữ liệu mẫu:

create table commissions (Agent Varchar2(100), Commission Number(3));
insert into commissions values ('Smith',100);
insert into commissions values ('Neo',200);
insert into commissions values ('Morpheus',300);

5

Bạn có thể thử truy vấn sau, tổng (hoa hồng) sẽ chỉ được tính một lần:

WITH TOTAL_COMMISSION AS 
(SELECT SUM(COMMISSION) AS TOTAL FROM AGENTS)
SELECT A.AGENT_NAME, A.COMMISSION, ((A.COMMISSION/T.TOTAL)*100) AS "% COMMISSION"
FROM AGENTS A, TOTAL_COMMISSION T;

Điều đó hoạt động và trả về dữ liệu chính xác, nhưng kém hiệu quả hơn một hàm phân tích thực hiện quét toàn bộ bảng chứ không phải hai (giả sử không có chỉ mục).
Leigh Riffel

1
@Leigh ~ Làm thế nào nó có thể làm điều đó trong một lần vì cách thủ công yêu cầu hai lần vượt qua? Tôi không thể thấy làm thế nào máy tính có thể biến% ofTotal thành một hoạt động vượt qua kỳ diệu ...
jcolebrand

@jcolebrand Dữ liệu chỉ được đọc từ các khối cơ sở dữ liệu một lần. Nó có thể thực hiện nhiều lần truyền kết quả trong bộ nhớ, nhưng điều này thường nhanh hơn việc đọc các khối cơ sở dữ liệu hai lần. Có sự đánh đổi trong bộ nhớ và CPU giữa các tùy chọn này, vì vậy sự lựa chọn có thể không phải lúc nào cũng rõ ràng, nhưng trong trường hợp này tôi nghĩ là như vậy.
Leigh Riffel

1
@Leigh ~ ~ Vâng, sự cân nhắc thêm sẽ khiến tôi tin rằng đó là tất cả những gì nó thể làm, chỉ cần tối ưu hóa hộp đen. Dù sao, một giải pháp tiện lợi trong câu trả lời của bạn. Cảm ơn: D
jcolebrand

0
  select 
  Agent, Commission,
  (
      ROUND(
       (Commission *100) / 
          (
            (SELECT SUM(Commission)
             FROM commissions AS A)
          )
       ) 
  ) AS Porcentaje
  from  
  commissions
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.