MYSQL Возвращать выходные данные с учетом сравнения с помощью группы по - PullRequest
2 голосов
/ 12 апреля 2019

У меня есть две таблицы: 1) BUYNSELL, 2) СТОК

ticker | buy_or_sell | date       | price | num_of_shares |
+--------+-------------+------------+-----------+-------+--
| IBM  | BUY         | 2019-03-20 | 273.0 | 1100          |
| IBM  | BUY         | 2019-03-21 | 271.0 | 2400          |
| IBM  | SELL        | 2019-03-22 | 270.5 | 2500          |
| GOOG | BUY         | 2019-03-20 | 86.0  | 2200          |
| GOOG | SELL        | 2019-03-20 | 87.0  |1000           |
| GOOG | SELL        | 2019-03-21 | 87.5  |1000           |
| GOOG | BUY         | 2019-03-21 | 87.0  | 800           |
| GOOG | SELL        | 2019-03-22 | 86.0  | 1000          |
| AAPL | BUY         | 2019-03-20 | 99.0  |1000           |
| AAPL | BUY         | 2019-03-20 | 99.5  | 1000          |
| AAPL | BUY         | 2019-03-21 | 100.0 |1000           |
| AAPL | SELL        | 2019-03-22 | 103.0 |3000           |
| MSFT | BUY         | 2019-03-20 | 186.0 | 1500          |
| MSFT | SELL        | 2019-03-21 | 188.0 |1000           |
| MSFT | BUY         | 2019-03-22 | 187.0 |5000           |

| ticker | exchange |
+--------+----------+
| AAPL   | NASDAQ   |
| GOOG   | NASDAQ   |
| MSFT   | NASDAQ   |
| IBM    | NYSE     |
| UNH    | NYSE     |

И я хочу найти даты, когда: цена * количество акций 'AAPL', где buy_or_sell = SELL, была выше, чем то, что фирма купила (buy_or_sell = BUY) в 'NASDAQ'. Я не хочу использовать какие-либо естественные соединения.

У меня есть запросы, которые достигают этого, но я не знаю, как правильно их объединить. Итак, у меня есть:

SELECT distinct A.date, A.ticker, SUM(A.price*A.num_of_shares) AS ‘TOTAL’ 
FROM BUYnSELL A, STOCK S 
WHERE A.ticker='AAPL' AND A.buy_or_sell = 'SELL' AND A.ticker = S.ticker 
GROUP BY A.date, A.ticker;

^ это возвращает даты, тикер и общую стоимость * количество акций только для яблока

А это:

SELECT distinct B.date, SUM(B.price*B.num_of_shares) AS 'BTOTAL' 
FROM BUYnSELL B, STOCK T 
WHERE B.ticker = T.ticker AND B.buy_or_sell = 'BUY' AND T.exchange = 'NASDAQ'
GROUP BY B.date, B.ticker;

^ возвращает даты и общую стоимость * количество акций, купленных только в NASDAQ

Кто-нибудь знает, как я могу объединить эти два запроса, чтобы он возвращал даты, когда сумма в первом превышает значения, указанные во втором запросе?

Таким образом, должна возвращаться только дата 2019-03-22, потому что стоимость яблока, проданного в тот день, выше любого из значений, которые возвращает второй запрос.

Новое в SQL и любые предложения приветствуются!

Ответы [ 2 ]

2 голосов
/ 12 апреля 2019

Вы можете использовать conditional aggregation:

SELECT A.date, A.ticker, 
       SUM( CASE WHEN A.buy_or_sell = 'SELL' AND A.ticker='AAPL' THEN 
                      A.price*A.num_of_shares
            END ) TOTAL_SELL,                  
       SUM( CASE WHEN A.buy_or_sell = 'BUY' AND S.exchange = 'NASDAQ' THEN
                      A.price*A.num_of_shares 
            END ) AS TOTAL_BUY
  FROM BUYnSELL A
  JOIN STOCK S ON S.ticker = A.ticker 
 GROUP BY A.date, A.ticker;

P.S. Предпочитайте использовать ANSI-92 синтаксис соединения вместо синтаксиса ANSI-89, у которого есть список таблиц, разделенных запятыми. Это легче читать и понимать.

1 голос
/ 12 апреля 2019

Очень простой способ:

select A.date from BUYnSELL as A, STOCK as B  
   where A.ticker = B.ticker 
   group by A.ticker, A.date
   having 
      sum(
         if(A.buy_or_sell='SELL' AND A.ticker = 'AAPL', 1,
         if(A.buy_or_sell='BUY' AND B.exchange = 'NASDAQ',-1,0)) 
         * A.price * A.num_of_shares) > 0; 

В основном: если это «ПРОДАВАТЬ» и «ЯБЛОКО», вы умножаете на 1 (добавьте).Если это «КУПИТЬ» и «NASDAQ», вы умножаете на -1 (вычитаете).В противном случае умножьте на 0 (ничего не делает).

В конце вы берете только положительные значения, то есть те, где SELL больше, чем BUY.

...