Warm tip: This article is reproduced from stackoverflow.com, please click
ms-access sql

Query in MS Access

发布于 2020-04-07 23:19:28

I have a table of tickers, the owner, and the number of shares, and want to produce a query showing total and percent of owner.

Here is dummy data:

+-------+--------+--------+
| Owner | Ticker | Shares |
+-------+--------+--------+
| Matt  | AAPL   |   2000 |
| Jed   | AAPL   |   8000 |
| Ron   | AAPL   |   4000 |
| Matt  | GE     |   3000 |
| Ron   | GE     |   1000 |
| Jed   | GOOG   |   5000 |
+-------+--------+--------+

And here is how I would like it to be:

+--------+--------------+------+------+-----+
| Ticker | Total Shares | Matt | Jed  | Ron |
+--------+--------------+------+------+-----+
| AAPL   |        14000 | 14%  | 57%  | 29% |
| GE     |         4000 | 75%  | 0%   | 25% |
| GOOG   |         5000 | 0%   | 100% | 0%  |
+--------+--------------+------+------+-----+
Questioner
Gabelli_IT
Viewed
45
Lee Mac 2020-02-04 02:15

The easiest way to solve this is using conditional aggregation.

Since you want the results by ticker, you group by the ticker field in column 1, sum the shares field to obtain column 2, and then use iif statements to calculate the percentage ownership for each of the remainining columns:

select
    t.ticker,
    sum(t.shares) as [Total Shares],
    sum(iif(t.owner='Matt',t.shares,0))/sum(t.shares) as Matt,
    sum(iif(t.owner='Jed',t.shares,0))/sum(t.shares) as Jed,
    sum(iif(t.owner='Ron',t.shares,0))/sum(t.shares) as Ron
from
    YourTable t
group by
    t.ticker
order by
    t.ticker

You can use formatting to convert the resulting decimal values into percentages.

Note that this approach does not scale well, as you are hard-coding field values into the query itself, but this approach is inevitable when transposing rows to columns, which goes against how most RDBMS like to operate.

A more scalable method might be to either use a correlated subquery, e.g.:

select  
    t1.ticker,
    t1.owner, 
    t1.shares/(select sum(t2.shares) from YourTable t2 where t2.ticker = t1.ticker) as pct
from 
    YourTable t1

Or a join on a query which calculates the total shares for each ticker, e.g.:

select t1.ticker, t1.owner, t1.shares/t2.shares as pct
from
    YourTable t1 inner join
    (
        select t.ticker, sum(t.shares) as shares 
        from YourTable t 
        group by t.ticker
    ) t2
    on t1.ticker = t2.ticker