Создать функцию / процедуру SQL из 3 таблиц - PullRequest
0 голосов
/ 22 июня 2019

У меня есть 3 таблицы, категория «Кадровый и кадровый план».

enter image description here

Я хочу рассчитать сумму Группировать по категориям

Я создал этот SQL-запрос:

select 
    CostCategory.CostCategory, sum(isnull(HRPplan.Amount, 0))
from 
    CostCategory
left join 
    HRPplan on HRPplan.Month between 1 and 3 
            and HRPplan.Year = 2019 
            and HRPplan.IDRPH in (select HumanResource.IDRPH 
                                  from HumanResource
                                  where HumanResource.IDCostCategory = CostCategory.IDCostegory)
group by  
    CostCategory.CostCategory

и он возвращает результат, но у меня есть еще две таблицы, точно похожие на Human Resource & HPlan, чтобы использовать их для вычисления суммы, поэтому, если я использую тот же код, упомянутый выше, производительность запроса не очень хорошая. И я не знаю, как использовать функцию / процедуру в SQL, так как год и месяц будут вставлены в качестве параметра.

Ответы [ 2 ]

1 голос
/ 24 июня 2019

Получение DDL и примеров данных DML в вопросах облегчает предоставление быстрого решения. Кроме того, столбцы, используемые в вашем запросе, не полностью соответствуют предоставленному вами снимку экрана, поэтому я предоставляю эти подходы на основе предоставленного снимка экрана.

Подготовленные DDL и данные испытаний:

DROP TABLE IF EXISTS CostCategory;
GO

CREATE TABLE CostCategory
(
    IDCostCategory  INT
    ,CostCategory   VARCHAR(10)
) ON [PRIMARY]
GO
INSERT INTO CostCategory
VALUES
(1, 'A'), (2, 'B'), (3, 'C')
GO


DROP TABLE IF EXISTS HumanResource;
GO

CREATE TABLE HumanResource
(
    IDHR            INT
    ,IDCostCategory INT
) ON [PRIMARY]
GO
INSERT INTO HumanResource
VALUES
(1, 1), (2, 2), (3, 2)
GO



DROP TABLE IF EXISTS HRPlan;
GO

CREATE TABLE HRPlan
(
    IDHRPlan        INT
    ,IDHR           INT
    ,Amount         INT
    ,Month          INT
    ,Year           INT
) ON [PRIMARY]
GO
INSERT INTO HRPlan
VALUES
    (1, 1, 10 , 1, 2019)
,   (2, 1, 12 , 2, 2019)
,   (3, 1, 15 , 2, 2019)
,   (4, 2, 50 , 1, 2019)
,   (5, 2, 0 , 2, 2019)
,   (6, 2, 100 , 3, 2019)
,   (4, 3, 40 , 1, 2019)
,   (5, 3, 50 , 2, 2019)
,   (6, 3, 30 , 3, 2019)
GO

Для отслеживания производительности вы можете включить статистику ввода-вывода и времени:

SET STATISTICS IO ON;
SET STATISTICS TIME ON;

Решение 1 : Использование Outer Apply (лучшая производительность, чем у решения № 2 ниже)

SELECT  CC.CostCategory, ISNULL(OA.Amount, 0)
FROM    CostCategory CC
        OUTER APPLY (
                        SELECT  Amount = SUM(ISNULL(HP.Amount, 0))
                        FROM    HRPlan HP
                        WHERE   HP.Month BETWEEN 1 AND 3
                        AND     HP.Year = 2019  
                        AND     EXISTS  (
                                            SELECT  1
                                            FROM    HumanResource HR
                                            WHERE   HR.IDCostCategory = CC.IDCostCategory
                                            AND     HR.IDHR = HP.IDHR
                                        )
                    ) OA;

Решение 2: Использование левого соединения

SELECT  CC.CostCategory, ISNULL(SUM(HP.Amount), 0)
FROM    CostCategory CC
        LEFT JOIN HumanResource HR
            ON  CC.IDCostCategory = HR.IDCostCategory
        LEFT JOIN HRPlan HP
            ON HR.IDHR = HP.IDHR
            AND HP.Month BETWEEN 1 AND 3
            AND HP.Year = 2019
GROUP   BY CC.CostCategory;

Примечание : - Вы можете подумать о создании индекса columnstore для таблицы HRPlan и создать индекс Rowstore / Columnstore для двух других таблиц, который охватывает соединения и выбранные столбцы для повышения производительности.

1 голос
/ 22 июня 2019

для повышения производительности вы можете избежать пункта in

select CostCategory.CostCategory, sum(isnull(HRPplan.Amount,0))
from CostCategory
left join HRPplan on HRPplan.Month between 1 and 3  and HRPplan.Year = 2019 
LEFT JOIN HumanResource ON HumanResource.IDCostCategory = CostCategory.IDCostegory
  and umanResource.IDRPH  = HRPplan.IDRPH 
group by CostCategory.CostCategory 
...