Это типичная проблема внутригрупповых агрегатов , которая решается с помощью левого самоисключающего соединения .
Вам не нужны никакие хранимые процедуры для получения желаемых результатов, достаточно простого запроса INSERT INTO ... SELECT ...
.
Вот пример сценария с предоставленными данными:
CREATE TABLE shuffled_symbols (
dat INT NOT NULL
,symbol VARCHAR(4) NOT NULL
,pct_return DECIMAL(4,2) NOT NULL
,PRIMARY KEY (dat ,symbol)
);
CREATE TABLE ranked_symbols (
dat INT NOT NULL
,symbol VARCHAR(4) NOT NULL
,pct_return DECIMAL(4,2) NOT NULL
,rank_asc INT UNSIGNED NOT NULL
,rank_desc INT UNSIGNED NOT NULL
);
INSERT INTO shuffled_symbols (dat,symbol,pct_return) VALUES (1100101,'IBM',1.2);
INSERT INTO shuffled_symbols (dat,symbol,pct_return) VALUES (1100101,'AAPL',2.1);
INSERT INTO shuffled_symbols (dat,symbol,pct_return) VALUES (1100101,'HPQ',-0.5);
INSERT INTO shuffled_symbols (dat,symbol,pct_return) VALUES (1100102,'IBM',-0.02);
INSERT INTO shuffled_symbols (dat,symbol,pct_return) VALUES (1100102,'AAPL',-0.6);
INSERT INTO shuffled_symbols (dat,symbol,pct_return) VALUES (1100102,'HPQ',1.9);
Вот запрос для вычисления рангов (извините за неправильное форматирование, я не мог заставить его правильно отображаться внутри тегов <pre>
):
INSERT INTO ranked_symbols (
dat, symbol, pct_return, rank_asc, rank_desc
) SELECT ars.dat, ars.symbol, ars.pct_return, ars.rank_asc, COUNT(ss3.dat)+1 rank_desc
FROM (
SELECT ss1.dat, ss1.symbol, ss1.pct_return, COUNT(ss2.dat)+1 rank_asc
FROM shuffled_symbols ss1
LEFT JOIN shuffled_symbols ss2
ON ss2.dat = ss1.dat
AND ss2.pct_return < ss1.pct_return
GROUP BY ss1.dat, ss1.symbol
) ars
LEFT JOIN shuffled_symbols ss3
ON ss3.dat = ars.dat
AND ss3.pct_return > ars.pct_return
GROUP BY ars.dat, ars.symbol
;
Обратите внимание, что этот запрос будет возвращать действительные ранги, только если у вас нет дубликатов символов на указанную дату. Вот почему я создал таблицу shuffled_symbols
с PRIMARY KEY (dat ,symbol)
.
В таблице ranked_symbols вы получите следующие результаты:
SELECT * FROM ranked_symbols;
+---------+--------+------------+----------+-----------+
| dat | symbol | pct_return | rank_asc | rank_desc |
+---------+--------+------------+----------+-----------+
| 1100101 | AAPL | 2.10 | 3 | 1 |
| 1100101 | HPQ | -0.50 | 1 | 3 |
| 1100101 | IBM | 1.20 | 2 | 2 |
| 1100102 | AAPL | -0.60 | 1 | 3 |
| 1100102 | HPQ | 1.90 | 3 | 1 |
| 1100102 | IBM | -0.02 | 2 | 2 |
+---------+--------+------------+----------+-----------+
6 rows in set (0.00 sec)