Как выполнить SUM () / SUM () в Linq - PullRequest
0 голосов
/ 01 мая 2019

Я пытаюсь выполнить этот SQL SELECT в моем приложении C #:

SELECT SUM( a.VALUE_A) / SUM( a.VALUE_B)
    FROM "TABLE" a
    WHERE DATE_COLUMN = to_date('12/05/2018', 'DD/MM/YYYY');

Использование этого C # с кодом LINQ:

dto.day = await database.Where(x => x.DATE_COLUMN.Date == date_filtered)
                        .SumAsync(x => (x.VALUE_A) / (x.VALUE_B));

Но это вызывает исключение, говорящее, что делитель это НОЛЬ. Итак, я попытался обработать это, добавив троичный IF внутри метода SumAsync ():

 dto.day = await database.Where(x => x.DATE_COLUMN.Date == date_filtered)
                         .SumAsync(x => x.VALUE_B == 0 ? 0 : (x.VALUE_A) / (x.VALUE_B));

Но конечный результат отличается от прямого результата SQL:

SQL дает правильный результат, например: 86.25

C # дает неверный результат: 227,87

Пожалуйста, что я делаю не так?

Ответы [ 2 ]

4 голосов
/ 01 мая 2019

Порядок работы является ключевым.Попробуйте следующее:

var values = database.Where(x => x.DATE_COLUMN.Date == date_filtered)
                     .Select(x => new {x.VALUE_A, x.VALUE_B}).ToList();
dto.day = values.Sum(s => s.VALUE_A) / values.Sum(s => s.VALUE_B);

РЕДАКТИРОВАТЬ:

Просто для ясности, вот разбивка.В вашем запросе вы делите сумму VALUE_A на сумму VALUE_B.

В своем операторе LINQ вы суммируете результаты VALUE_A / VALUE_B каждой записи.

Inмой ответ, я создаю анонимный объект, где я получаю только VALUE_A и VALUE_B.Затем я беру сумму каждого и делю их друг на друга.Надеюсь, это лучшее объяснение.

1 голос
/ 01 мая 2019

Вы получаете неправильный результат, потому что Sum(a) / Sum(b) отличается от Sum(a / b). То, что вы хотите, это

(a1 + a2 + ... aN) / (b1 + b2 + ...bN)

пока вы получаете

(a1 / b1 + a2 / b2 + ... aN / bN)

Таким образом, чтобы получить желаемый результат, в LINQ обычно требуется 2 Sum вызовов для результата GroupBy или подобного набора. Поскольку ваш запрос относится к верхнему уровню, вы можете либо выполнить 2 запроса к базе данных Sum и рассчитать их результат, либо использовать поддельную группу с помощью постоянной уловки, чтобы получить ее с помощью одного запроса к базе данных. Примерно так:

var query = db.Table
    .Where(e => e.DATE_COLUMN.Date == date_filtered)
    .GroupBy(e => 1) // <--
    .Select(g => new
    {
        SumA = g.Sum(e => e.VALUE_A), // <--
        SumB = g.Sum(e => e.VALUE_B), // <--
    })
    .Select(e => e.SumB == 0 ? 0 : e.SumA / e.SumB);

var result = await query.FirstOrDefaultAsync();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...