Вычитать два SELECT в другой SELECT в SQLAlchemy? - PullRequest
0 голосов
/ 06 апреля 2019

Я пытаюсь вычесть результаты двух разных вызовов select в SQLAlchemy как еще один select, чтобы наконец вызвать order_by, чтобы воссоздать следующий запрос:

SELECT reviews.id FROM reviews
ORDER BY (
    SELECT (
        SELECT COUNT(*) FROM review_upvoters WHERE review_id = reviews.id
    ) - (
        SELECT COUNT(*) FROM review_downvoters WHERE review_id = reviews.id
    )
);

Я попытался просто вычесть два выбора друг из друга (query_one - query_two), два безрезультатно, и просмотр документов SQLAlchemy, но они точно не помогли.

То, что у меня сейчас есть, это:

upvoters_count = select([func.count()]).where(ReviewUpvoters.review_id == Review.id)
downvoters_count = select([func.count()]).where(ReviewDownvoters.review_id == Review.id)
reviews = Reviews.query.order_by(...)

, где я пытаюсь выяснить внутреннюю часть order_by, чтобы правильно вычесть эти select s.

(Если Reviews.query выглядит странно, это потому, что я использую Gino для асинхронной поддержки Postgres, но в большинстве случаев он использует обычные объекты SQLAlchemy, поэтому это ни на что не должно влиять.)

Поскольку __sub__ не представляется определенным для Select объектов, я немного озадачен этим, и я не на 100% заинтересован в реструктуризации таблиц, поэтому эти два находятся в одной таблице с чем-то, чтобы дифференцировать их.

Ответы [ 2 ]

0 голосов
/ 07 апреля 2019

Благодаря @Tryph я получил его, используя as_scalar() в подзапросах.

upvoters_count = select([func.count()]).where(ReviewUpvoters.review_id == Review.id).as_scalar()
downvoters_count = select([func.count()]).where(ReviewDownvoters.review_id == Review.id).as_scalar()
query = Reviews.query.order_by(upvoters_count - downvoters_count)

, который производит следующий запрос, сравнимый с моим исходным

SELECT reviews.id, reviews.created_at, reviews.rating, reviews.content, reviews.title, reviews.mod_id, reviews.author_id
FROM reviews
ORDER BY (
    SELECT count(*) AS count_1
    FROM review_upvoters
    WHERE review_upvoters.review_id = reviews.id
) - (
    SELECT count(*) AS count_2
    FROM review_downvoters
    WHERE review_downvoters.review_id = reviews.id
);
0 голосов
/ 06 апреля 2019

Почему бы не провести рефакторинг этого запроса? Я думаю, что это было бы быстрее, и это определенно упростило бы то, что вы должны попросить sqlalchemy.

SELECT reviews.id
FROM reviews
LEFT JOIN review_upvoters ON reviews.id = review_upvoters.review_id
LEFT JOIN review_downvoters ON reviews.id = review_downvoters.review_id
GROUP BY reviews.id
ORDER BY
COUNT(DISTINCT review_upvoters.id) - COUNT(DISTINCT review_downvoters.id)
;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...