SUM () и AVERAGE () обернуты в CAST - PullRequest
       0

SUM () и AVERAGE () обернуты в CAST

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

У меня есть стол TRANSACTIONS.Он довольно большой, поэтому есть его часть:

CREATE TABLE [dbo].[TRANSACTIONS] 
(
    [transaction_ID]             UNIQUEIDENTIFIER NOT NULL,
    [transaction_number]         INT              IDENTITY (1000, 1) NOT NULL,
    [type_id]                    INT              NOT NULL,
    [source_currency_ID]         INT              NOT NULL,
    [target_currency_ID]         INT              NOT NULL,
    [source_value]               NUMERIC (14, 6)  NOT NULL,
    [target_value]               NUMERIC (14, 6)  NOT NULL,
    [user_account_source]        NVARCHAR (500)   NULL,
    [user_account_target]        NVARCHAR (500)   NULL,
    [user_wmid]                  VARCHAR (12)     NULL,
    [user_email]                 NVARCHAR (51)    NULL,
    [create_date]                DATETIME         CONSTRAINT [DF__transacti__creat__589C25F3] DEFAULT (getdate()) NOT NULL,
    [card_ID]                    INT              NULL,
    [payment_ID]                 NVARCHAR (80)    NULL,
    [enable_automation]          BIT              CONSTRAINT [DF__transacti__enabl__3AA1AEB8] DEFAULT ((1)) NOT NULL,
    [client_ID]                  UNIQUEIDENTIFIER NULL,
    [partner_ID]                 INT              NULL,
    [payment_type_ID]            INT              NOT NULL,
    [language_ID]                INT              NULL,
    [member_id]                  NUMERIC (18)     NULL,
    [desk_id]                    INT              NULL,
    [source_member_discount]     NUMERIC (18, 3)  NULL,
    [member_scores]              INT              NULL,
    [source_eps_fee_from_customer]  NUMERIC (18, 6)  NULL,
    [source_eps_fee]             NUMERIC (18, 6)  NOT NULL,
    [source_eps_fee_actual]      NUMERIC (18, 6)  NULL,
    [target_eps_fee]             NUMERIC (18, 6)  NOT NULL,
    [target_eps_fee_actual]      NUMERIC (18, 6)  NULL,
    [target_exchanger_fee]       NUMERIC(18, 6)   NOT NULL DEFAULT 0, 
    [exchange_rate]              NUMERIC (20, 9)  NULL,
    [source_master]              BIT              NULL,
    [manual_rate]                NUMERIC (20, 9)  NULL,
    [cb_cross_rate]              NUMERIC (20, 9)  NULL,
    [source_profit]              NUMERIC (18, 6)  NULL,
    [partner_reward]             NUMERIC (18, 6)  NULL,
    [source_service_profit]      NUMERIC (18, 6)  NULL,
    [is_individual]              BIT              NULL,
    [member_discount]            NUMERIC (18)     NULL,
    [scores]                     INT              NULL,
    [return_url]                 VARCHAR (300)    NULL,
    [err_return_url]             VARCHAR (300)    NULL,
    [add_scores]                 BIT              NULL,
    [mm_transaction_id]          NVARCHAR (80)    NULL,
    [lp_transaction_id]          NVARCHAR (50)    NULL,
    [masterbank_auth_ID]         NVARCHAR (50)    NULL,
    [cardtype]                   NVARCHAR (50)    NULL,
    [cl_num]                     INT              NULL,
    [cl_date]                    NVARCHAR (50)    NULL,
    [limit_check_day]            BIT              NULL,
    [limit_check_month]          BIT              NULL,
    [rapida_temp]                NVARCHAR (50)    NULL,
    [ecard_id]                   BIGINT           NULL,
    [card_payment_complete]      VARCHAR (4)      CONSTRAINT [DF_TRANSACTIONS_card_payment_complete] DEFAULT ('NO') NULL,
    [profit_in_rub]              NUMERIC (18, 4)  NULL,
    [cb_rub_rate]                NUMERIC (18, 4)  NULL,
    [check_wmid]                 VARCHAR (12)     NULL,
    [partner_rate]               NUMERIC (18, 4)  NULL,
    [wm_desc]                    VARCHAR (500)    NULL,
    [without_real]               BIT              NULL,
    [netex_point]                UNIQUEIDENTIFIER NULL,
    [secret_key]                 INT              NULL,
    [miniport_transfer]          BIT              NULL,
    [miniport_hold]              BIT              NULL,
    [hold_time]                  DATETIME         NULL,
    [is_from_widget]             BIT              NULL,
    [partner_reward_currency_id] INT              NULL,
    [user_phone]                 NVARCHAR (50)    NULL,
    [project_ID]                 INT              NOT NULL DEFAULT 2,
...

Из которого я составляю нужные мне данные SELECT:

return query
            .Where(x => x.CurrentStatus == TransactionStatus.PaymentSent)
            .GroupBy(x => new { SourceCurrency = x.SourceCurrency, TargetCurrency = x.TargetCurrency })
            .Select(x => new ProfitabilityReportEntry
            {
                SourceCurrencyCode = x.Key.SourceCurrency,
                TargetCurrencyCode = x.Key.TargetCurrency,
                TransactionsCount = x.LongCount(),
                TotalProfitRub = x.Sum(y => y.ProfitInRub),
                AverageProfitRub = x.Average(y => y.ProfitInRub),
                AverageAmountRub = x.Average(y => y.SourceValue * y.CbRubRate),
                TotalAmountRub = x.Sum(y => y.SourceValue * y.CbRubRate)
            })
            .ToList();

Класс ProfitabilityReportEntry:

public class ProfitabilityReportEntry
{
    public PaymentCurrencyCode SourceCurrencyCode { get; set; }
    public PaymentCurrencyCode TargetCurrencyCode { get; set; }
    public long TransactionsCount { get; set; }
    public decimal? AverageAmountRub { get; set; }
    public decimal? AverageProfitRub { get; set; }
    public decimal? TotalAmountRub { get; set; }
    public decimal? AmountTurnoverPercent { get; set; }
    public decimal? TotalProfitRub { get; set; }
    public decimal? ProfitPercent { get; set; }
}

В отображаемом классе Transaction (до TRANSACTIONS) свойства, которые суммируют и усредняют в запросе выше, также являются десятичными.

И мой запрос приводит к следующему оператору SQL:

select transactio0_.source_currency_ID as col_0_0_, transactio0_.target_currency_ID as col_1_0_, 
    cast(count(*) as BIGINT) as col_2_0_, 
    cast(sum(transactio0_.moneyback_profit_rub) as DECIMAL(19,5)) as col_3_0_,
    cast(avg(transactio0_.moneyback_profit_rub) as DECIMAL(19,5)) as col_4_0_, 
    cast(avg(transactio0_.source_value*transactio0_.cb_rub_rate) as DECIMAL(19,5)) as col_5_0_,
    cast(sum(transactio0_.source_value*transactio0_.cb_rub_rate) as DECIMAL(19,5)) as col_6_0_ 
    from TRANSACTIONS transactio0_ 
    where transactio0_.change_date>? and transactio0_.change_date<? and transactio0_.status_id=? group by transactio0_.source_currency_ID, transactio0_.target_currency_ID

Проблема в том, почему существуют приведения, почему NHibernate генерирует их?Как заставить NH избавиться от них?И я думаю, что они тоже влияют на производительность.

Почему десятичное суммирование приводится к десятичному?Кроме того, если я использую анонимный тип, приведения остаются.

Моя версия Fluent NHibernate - 2.0.3 и NHibernate 5.2.1

1 Ответ

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

Например, source_value имеет тип NUMERIC (14, 6), а cb_rub_rate имеет тип NUMERIC (18, 4).Итак, какой тип вы ожидаете получить в результате source_value * cb_rub_rat?

Я думаю, вы должны сделать типы полей равными друг другу.

Но это не влияет на производительность, ясчитать.Все CAST операторы используются в результатах выражений, поэтому он выполняется один раз.

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