SQL Server 2008: итоговые и нулевые записи - PullRequest
0 голосов
/ 09 октября 2019

У меня есть несколько запросов, которые получают остатки на счетах от нашей ERP, но есть несколько проблем, которые я пытаюсь обойти, и мне любопытно, есть ли более эффективные способы или если более свежие версии SQL Server имеют функции для решения какой-либо из этих проблемпроблемы.

  • Наша ERP создает запись баланса только в те периоды, когда есть активность, связанная с учетной записью. Приложения и отчеты ERP суммируют значения по периодам, но никакие записи не добавляются в базу данных, поэтому для пользовательских процессов, которым требуется баланс по периодам, требуется запрос / представление для вычисления этой информации.

    Мой обходной путь для этого заключается в использовании глобальной переменной для преднамеренного создания дубликатов из таблицы Account и созданной мною таблицы псевдопериодов, см. Ниже

  • НашДоза в таблице «Период счета» не содержит индекса периода (я полагаю, это должен быть идентификатор строки, однако в какой-то момент финансовый период был добавлен неправильно, и индекс был выведен из строя. Поставщик ERP посоветовал мне не обновлять его безполное переопределение). Я создал обходную таблицу для этого.

Итак, у меня есть несколько запросов, которые решают эти проблемы, но они выполняются медленно с небольшим количеством учетных записей, поэтому полная псевдо-таблица для остатков на счетах не имеетбыл практичным с моими методами по крайней мере.

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

SELECT 
    ID AS ACCOUNT_ID, ind.Month_Index, ind.Period,
    (SELECT 
         ISNULL(SUM(CASE WHEN A3.TYPE IN ('e','r') THEN NULL
                         WHEN A3.TYPE = 'a' THEN ISNULL(AB3.DEBIT_AMOUNT, 0) - ISNULL(AB3.CREDIT_AMOUNT, 0) 
                         ELSE ISNULL(AB3.CREDIT_AMOUNT, 0) - ISNULL(AB3.DEBIT_AMOUNT, 0) END), 0)
     FROM ACCOUNT_BALANCE AS AB3
     LEFT OUTER JOIN ACCOUNT AS A3 ON AB3.ACCOUNT_ID = A3.ID
     LEFT OUTER JOIN  
         (SELECT YEAR, Month_Num, Month_Index, Period
          FROM UFC_Calander 
          GROUP BY YEAR, Month_Num, Month_Index, Period) AS ind2 ON AB3.ACCT_YEAR = ind2.YEAR AND AB3.ACCT_PERIOD = ind2.Month_Num
     WHERE A.ID = AB3.ACCOUNT_ID 
       AND A3.CURRENCY_ID = '(USA) $' 
       AND ind2.Month_Index <= ind.Month_Index) AS BALANCE_AQL
FROM 
    ACCOUNT AS A
LEFT OUTER JOIN 
    ACCOUNT_PERIOD AS per ON 'UCC' = per.SITE_ID
LEFT OUTER JOIN 
    ACCOUNT_BALANCE AS AB ON A.ID = AB.ACCOUNT_ID 
                          AND per.ACCT_YEAR = AB.ACCT_YEAR 
                          AND per.ACCT_PERIOD = AB.ACCT_PERIOD 
                          AND AB.CURRENCY_ID = '(USA) $'
LEFT OUTER JOIN 
    (SELECT YEAR, Month_Num, Month_Index, Period
     FROM UFC_Calander 
     GROUP BY YEAR, Month_Num, Month_Index, Period) AS ind ON per.ACCT_YEAR = ind.YEAR AND per.ACCT_PERIOD = ind.Month_Num
WHERE 
    ID IN  ('120-1140-0000', '120-1190-1190', '120-1190-1193', 
            '120-1190-1194', '210-2100-0000', '210-2101-0000') 
GROUP BY 
    ID, ind.Month_Index, ind.Period
ORDER BY 
    ind.Month_Index DESC, ACCOUNT_ID DESC

Любые предложения, которые могут улучшитьпроизводительность этого запроса будет принята с благодарностью.

1 Ответ

0 голосов
/ 09 октября 2019

Мои рекомендации высокого уровня следующие:

  • Избегайте использования предложения IN. Если возможно (при условии, что таблица учетных записей не слишком большая, создайте временную таблицу только для тех столбцов, которые вам нужны, и загрузите эти данные с идентификаторами, с которыми вы работаете.) Затем используйте это в приведенном выше коде.

  • (не производительность, а скорее небольшое изменение). Часть ISNULL (SUM ... необходима только потому, что у вас есть «A3.TYPE IN ('e', 'r') THEN NULL". Если вы сказали THEN 0, вы можете избежать проверки на нулевое значение.

  • С коррелированным подзапросом в пределах выбора все в порядке, но это соединение из нескольких частей, которое, скорее всего, вызывает его замедление. Я не уверен на 100% уверен в том, как вы можете сломать этоткроме того, чтобы быть двумя отдельными логическими захватами данных и затем соединенными вместе, но это лучшее, что я получил с тем, что я вижу здесь.

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