Đầu tiên, hãy tạo một số dữ liệu thử nghiệm:
create table client (client_id integer not null primary key auto_increment,
name varchar(64));
create table portfolio (portfolio_id integer not null primary key auto_increment,
client_id integer references client.id,
cash decimal(10,2),
stocks decimal(10,2));
insert into client (name) values ('John Doe'), ('Jane Doe');
insert into portfolio (client_id, cash, stocks) values (1, 11.11, 22.22),
(1, 10.11, 23.22),
(2, 30.30, 40.40),
(2, 40.40, 50.50);
Nếu bạn không cần ID danh mục đầu tư, thật dễ dàng:
select client_id, name, max(cash + stocks)
from client join portfolio using (client_id)
group by client_id
+-----------+----------+--------------------+
| client_id | name | max(cash + stocks) |
+-----------+----------+--------------------+
| 1 | John Doe | 33.33 |
| 2 | Jane Doe | 90.90 |
+-----------+----------+--------------------+
Vì bạn cần ID danh mục đầu tư, mọi thứ trở nên phức tạp hơn. Hãy làm điều đó trong các bước. Đầu tiên, chúng tôi sẽ viết một truy vấn con trả về giá trị danh mục đầu tư tối đa cho mỗi khách hàng:
select client_id, max(cash + stocks) as maxtotal
from portfolio
group by client_id
+-----------+----------+
| client_id | maxtotal |
+-----------+----------+
| 1 | 33.33 |
| 2 | 90.90 |
+-----------+----------+
Sau đó, chúng tôi sẽ truy vấn bảng danh mục đầu tư, nhưng sử dụng một phép nối với truy vấn con trước đó để chỉ giữ cho những danh mục đầu tư đó có tổng giá trị là giá trị tối đa cho khách hàng:
select portfolio_id, cash + stocks from portfolio
join (select client_id, max(cash + stocks) as maxtotal
from portfolio
group by client_id) as maxima
using (client_id)
where cash + stocks = maxtotal
+--------------+---------------+
| portfolio_id | cash + stocks |
+--------------+---------------+
| 5 | 33.33 |
| 6 | 33.33 |
| 8 | 90.90 |
+--------------+---------------+
Cuối cùng, chúng tôi có thể tham gia vào bảng khách hàng (như bạn đã làm) để bao gồm tên của từng khách hàng:
select client_id, name, portfolio_id, cash + stocks
from client
join portfolio using (client_id)
join (select client_id, max(cash + stocks) as maxtotal
from portfolio
group by client_id) as maxima
using (client_id)
where cash + stocks = maxtotal
+-----------+----------+--------------+---------------+
| client_id | name | portfolio_id | cash + stocks |
+-----------+----------+--------------+---------------+
| 1 | John Doe | 5 | 33.33 |
| 1 | John Doe | 6 | 33.33 |
| 2 | Jane Doe | 8 | 90.90 |
+-----------+----------+--------------+---------------+
Lưu ý rằng điều này trả về hai hàng cho John Doe vì anh ta có hai danh mục đầu tư với tổng giá trị chính xác giống nhau. Để tránh điều này và chọn một danh mục đầu tư hàng đầu tùy ý, hãy gắn thẻ vào mệnh đề GROUP BY:
select client_id, name, portfolio_id, cash + stocks
from client
join portfolio using (client_id)
join (select client_id, max(cash + stocks) as maxtotal
from portfolio
group by client_id) as maxima
using (client_id)
where cash + stocks = maxtotal
group by client_id, cash + stocks
+-----------+----------+--------------+---------------+
| client_id | name | portfolio_id | cash + stocks |
+-----------+----------+--------------+---------------+
| 1 | John Doe | 5 | 33.33 |
| 2 | Jane Doe | 8 | 90.90 |
+-----------+----------+--------------+---------------+