Использование HAVING для фильтрации по сумме вложенной модели в Sequelize Postgres - PullRequest
0 голосов
/ 23 мая 2018

У меня есть структура данных в Postgres, такая как:

Пожертвования

id  amount  status
1   5000    OK
2   7500    OK

Пожертвования

id  donationId  amount  includeInTotals
1   1           2500    false
2   1           2500    false
3   2           7500    false

В псевдо-SQL я пытаюсь сделать что-то вроде:

SELECT * FROM donations WHERE SUM(SELECT donation.items WHERE "donationId" = "donations"."id" AND "includeInTotals" = false) >= "donations"."amount"

По сути, хочу удалить пожертвования, где общее количество элементов пожертвования "includeInTotals = false" одинаковов качестве значения пожертвования.

Это код, который я получил для Sequelize:

Models.donations.findAndCountAll({
   where: { status: 'OK' },
   include: {
        model: Models.donation_items,
        as: 'items',
        duplicating: false,
    },
   having: sequelize.literal('COALESCE(SUM(CASE WHEN "items"."includeInTotals" = false THEN items.amount ELSE 0 END), 0) < "donations"."amount"'),
   group: ['"donations.id"', '"items.id"']
});

Это работает для ID пожертвования: 2 - это не таквозвращается по запросу, но ID пожертвования: 1 есть, несмотря на две суммы, равные 5000.

Что-то не так, я делаю с SUM?

Ответы [ 2 ]

0 голосов
/ 23 мая 2018

Похоже, что предложение GROUP здесь объединяло элементы пожертвования и возвращало неверную сумму, поэтому я переключился на подзапрос в предложении WHERE.Я добавил это к своему where, который работал для меня!

amount: {
        $gt: globals.sequelize.literal(`
            (SELECT COALESCE(SUM(amount), 0) FROM donation_items
            WHERE "donation_items"."includeInTotals" = false
            AND "donation_items"."donationId" = "donations"."id")
        `),
},
0 голосов
/ 23 мая 2018

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

SELECT d1.*
FROM Donations d1
LEFT JOIN
(
    SELECT donationId, SUM(amount) AS amount
    FROM DonationItems di
    WHERE includeInTotals = false
    GROUP BY donationId
) d2
    ON d1.id = d2.donationId AND d1.amount = d2.amount
WHERE
    d2.donationId IS NULL;

Хотя это не касается вашей проблемы секвелирования, наличие правильного необработанного запроса является полной предпосылкой для выполнения чего-либов PHP, который принесет плоды позже.Есть другие, более эффективные способы, которыми мы могли бы написать этот запрос, но приведенную выше версию, вероятно, было бы проще всего интегрировать в ваш PHP-код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...