Получить строки на основе наличия связанных строк в той же таблице - PullRequest
0 голосов
/ 02 декабря 2018

Вот как выглядят мои данные.Если я сделаю следующий запрос:

select * from gdax_trades where order_type='limit' limit 5;

Я получу возврат, который выглядит следующим образом:

 row_id  |               order_id               |  price  | funds | maker_order_id | taker_order_id | trade_id | product_id |              client_oid              | reason | remaining_size |    size    |  sequence  | side |          time           | order_type | event_type 
---------+--------------------------------------+---------+-------+----------------+----------------+----------+------------+--------------------------------------+--------+----------------+------------+------------+------+-------------------------+------------+------------
 3697499 | 01d63a5b-a5b7-4153-b93d-bd18c249d9c3 | 4113.06 |       |                |                |          | BTC-USD    | 50028bab-81da-4842-98f0-2a1206669567 |        |                |       0.01 | 7446101470 | buy  | 2018-11-29 04:15:39.047 | limit      | received
 3697501 | 9295111b-2e23-445c-9f52-52d2f26fb418 | 4131.93 |       |                |                |          | BTC-USD    | de58f4a6-4577-4680-b083-df34ade6c001 |        |                | 0.12792387 | 7446101472 | sell | 2018-11-29 04:15:39.071 | limit      | received
 3697504 | 4c09878d-8bf9-49d7-9fc7-ca81b7da9e42 | 4131.19 |       |                |                |          | BTC-USD    | a55e0315-8b65-4525-a7a7-debcf6f17bb5 |        |                | 0.10898271 | 7446101475 | sell | 2018-11-29 04:15:39.155 | limit      | received
 3697506 | 0a157570-a811-420e-81ff-0ead9cc34984 | 4132.69 |       |                |                |          | BTC-USD    | 45086077-34be-441e-947f-99fe60bd88ef |        |                | 0.12146031 | 7446101477 | sell | 2018-11-29 04:15:39.24  | limit      | received
 3697508 | e8e1d02f-e627-4eac-a2e5-61c08399d6ef | 4117.83 |       |                |                |          | BTC-USD    | 00000000-818a-0006-0001-000011037107 |        |                |      0.001 | 7446101479 | sell | 2018-11-29 04:15:39.259 | limit      | received
(5 rows)

В таблице есть другие строки, соответствующие каждому order_id, но неиметь order_type='limit'.Например, если я пытаюсь найти все строки, которые соответствуют первому order_id:

select * from gdax_trades where order_id='01d63a5b-a5b7-4153-b93d-bd18c249d9c3';

, я получу:

 row_id  |               order_id               |  price  | funds | maker_order_id | taker_order_id | trade_id | product_id |              client_oid              |  reason  | remaining_size | size |  sequence  | side |          time           | order_type | event_type 
---------+--------------------------------------+---------+-------+----------------+----------------+----------+------------+--------------------------------------+----------+----------------+------+------------+------+-------------------------+------------+------------
 3697499 | 01d63a5b-a5b7-4153-b93d-bd18c249d9c3 | 4113.06 |       |                |                |          | BTC-USD    | 50028bab-81da-4842-98f0-2a1206669567 |          |                | 0.01 | 7446101470 | buy  | 2018-11-29 04:15:39.047 | limit      | received
 3697500 | 01d63a5b-a5b7-4153-b93d-bd18c249d9c3 | 4113.06 |       |                |                |          | BTC-USD    |                                      |          |           0.01 |      | 7446101471 | buy  | 2018-11-29 04:15:39.047 |            | open
 3697662 | 01d63a5b-a5b7-4153-b93d-bd18c249d9c3 | 4113.06 |       |                |                |          | BTC-USD    |                                      | canceled |           0.01 |      | 7446101633 | buy  | 2018-11-29 04:15:40.522 |            | done
(3 rows)

То, что я хочу, - это запрос SQLAlchemy, который возвращаетme строки с order_id, соответствующим «предельному» порядкуЯ попытался сделать самоссылочное соединение:

GDAXTradeAlias = aliased(GDAXTrade)

orders = (
    sess
    .query(GDAXTrade)
    .filter( GDAXTrade.time.between(start_dt, end_dt) )
    .filter(GDAXTrade.order_type=='limit')
    .join(GDAXTradeAlias, GDAXTrade.order_id==GDAXTradeAlias.order_id)
    .filter( GDAXTrade.time.between(start_dt, end_dt) )
    .all() )

, но это не дало мне желаемого результата.У кого-нибудь есть совет?

Ответы [ 2 ]

0 голосов
/ 02 декабря 2018

Я нашел ответ, используя подзапросы.Мне интересно, что люди думают об этом

    sub_query = ( 
        sess
        .query(GDAXTrade)
        .filter( GDAXTrade.time.between(start_dt, end_dt) )
        .filter(GDAXTrade.order_type=='limit')
        .subquery() 
        )

    orders = (
        sess
        .query(GDAXTrade)
        .join(sub_query, GDAXTrade.order_id==sub_query.c.order_id, isouter=True)
        .filter(GDAXTrade.order_id==sub_query.c.order_id)
        .filter( GDAXTrade.time.between(start_dt, end_dt) )
        .order_by(GDAXTrade.time.asc())
        .all()
        )
0 голосов
/ 02 декабря 2018

Возможно много способов.Я предлагаю EXISTS полусоединение.Вероятно, самый быстрый и очень понятный для чтения:

SELECT *
FROM   gdax_trades g
WHERE  EXISTS (
   SELECT FROM gdax_trades
   WHERE  order_type = 'limit'
   AND    order_id = g.order_id
   );

Список SELECT выражения EXISTS может оставаться пустым.Относительно только наличие хотя бы одной строки.

Нам нужен хотя бы один псевдоним таблицы (g в примере) при двойном обращении к одной и той же таблице.Я не указывал столбцы с указанием таблицы, ссылающиеся на локальную таблицу внутри подзапроса, так как это видно в первую очередь.Ссылка на внешний запрос только квалифицируется как g.order_id.Это минимальное требование, чтобы быть однозначным.Вы можете быть более точным, если хотите.

Это включает в себя"предельные" ордера в результате.Вы можете легко исключить их, добавив окончательный вариант:

...
WHERE order_type IS DISTINCT FROM 'limit'

IS DISTINCT FROM, потому что order_type кажется обнуляемым (неясно, являются ли они '' или NULL в вашемобразец результата).WHERE order_type <> 'limit' исключит строки с order_type IS NULL.

Запрос возвращает уникальные строки из внешней таблицы, даже если существует несколько «лимитных» ордеров с одинаковым order_id.Различные альтернативные методы запросов с объединениями или подзапросами в этом случае возвращают дубликаты.Связанный:

...