Есть ли лучший способ суммировать столбцы?

У меня есть ответ, который мне нужен, но я спрашиваю, есть ли лучший способ получить тот же ответ. «4» будет параметром ThisMonth. Я пытаюсь получить цифры бюджета с начала года. В таблице нет столбца даты, отсюда и такой странный способ получения СУММЫ на основе периода.

SELECT СASE 
         WHEN 4 <= 1 THEN SUM(Period.A)
         WHEN 4 <= 2 THEN SUM(Period.A) + SUM(Period.B)
         WHEN 4 <= 3 THEN SUM(Period.A) + SUM(Period.B) + SUM(Period.C)
         WHEN 4 <= 4 THEN SUM(Period.A) + SUM(Period.B) + SUM(Period.C) + SUM(Period.D)
         WHEN 4 <= 5 THEN SUM(Period.A) + SUM(Period.B) + SUM(Period.C) + SUM(Period.D) 
                        + SUM(Period.E)
         WHEN 4 <= 6 THEN SUM(Period.A) + SUM(Period.B) + SUM(Period.C) + SUM(Period.D) 
                        + SUM(Period.E) + SUM(Period.F)
         WHEN 4 <= 7 THEN SUM(Period.A) + SUM(Period.B) + SUM(Period.C) + SUM(Period.D) 
                        + SUM(Period.E) + SUM(Period.F) + SUM(Period.G)
         WHEN 4 <= 8 THEN SUM(Period.A) + SUM(Period.B) + SUM(Period.C) + SUM(Period.D) 
                        + SUM(Period.E) + SUM(Period.F) + SUM(Period.G) + SUM(Period.H)
      ELSE 0 
      END AS [LaborCOGS-CO],
   '0' AS [LaborCOGS-AO], '0' AS IndirectLabor,
   '0' AS MiscExpense,    '0' AS LabelCost,
   '0' AS BuildMaint,     '0' AS ShipCost,
   '0' AS RDR,            '0' AS NetSales
From GLAccountBudgetDetails
LEFT JOIN GLAccountBudget WITH(NOLOCK) 
    ON GLAccountBudgetDetails.GLAccountBudgetID = GLAccountBudget.GLAccountBudgetID
LEFT JOIN
( SELECT GLAccountBudgetDetailID,[BudgetAmtPeriod1] A,[BudgetAmtPeriod2] B,
     [BudgetAmtPeriod3] C,[BudgetAmtPeriod4] D,[BudgetAmtPeriod5] E,
     [BudgetAmtPeriod6] F,[BudgetAmtPeriod7] G,[BudgetAmtPeriod8] H,
     [BudgetAmtPeriod9] I,[BudgetAmtPeriod10] J,[BudgetAmtPeriod11] K,
     [BudgetAmtPeriod12] L
  From GLAccountBudgetDetails
) AS Period 
   ON GLAccountBudgetDetails.GLAccountBudgetDetailID = [Period].GLAccountBudgetDetailID
WHERE GLAccountBudgetDetails.GLAccountID IN(256,257,258,266) 
   AND GLAccountBudget.FiscalYear = 2024

Это таблица GLAccountBudgetDetails. Все последние четыре столбца имеют значение NULL, так что это бесполезно.

COLUMN_NAME DATA_TYPE
GLAccountBudgetDetailID int
GLAccountBudgetID   int
GLAccountID int
BudgetAmtPeriod1    float
BudgetAmtPeriod2    float
BudgetAmtPeriod3    float
BudgetAmtPeriod4    float
BudgetAmtPeriod5    float
BudgetAmtPeriod6    float
BudgetAmtPeriod7    float
BudgetAmtPeriod8    float
BudgetAmtPeriod9    float
BudgetAmtPeriod10   float
BudgetAmtPeriod11   float
BudgetAmtPeriod12   float
BudgetAmtPeriod13   float
BudgetAmtPeriod14   float
BudgetAmtPeriod15   float
UserCreated varchar
DateCreated datetime
UserModified    varchar
DateModified    datetime

Вот таблица GLAccountBudget.

COLUMN_NAME DATA_TYPE
GLAccountBudgetID   int
Name    varchar
FiscalYear  int
DefaultBudget   bit
UserCreated varchar
DateCreated datetime
UserModified    varchar
DateModified    datetime

Ответ: «В таблице нет столбца даты, отсюда и такой странный способ....», или на codereview.stackexchange.com . на dba.stackexchange.com они предложили бы добавить index.

Luuk 18.04.2024 21:44

@Luuk Я не владею базой данных, однако предлагаете ли вы мне добавить индекс для каждой группы столбцов вместо того, чтобы называть их отдельно??

Michael Tuma 18.04.2024 22:01

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

Luuk 18.04.2024 22:26

Дабл (сам) Присоединяйтесь GLAccountBudgetDetails.GLAccountBudgetDetailID = [Period].GLAccountBudgetDetailID кажется совершенно ненужным.

ValNik 18.04.2024 23:57

Пожалуйста, взгляните на: Реальные, с плавающей запятой и деньги и Что такое DDL и DML?

Luuk 19.04.2024 20:33
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
2
6
71
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Вот упрощенная версия вашей проблемы.

create table bad_schema (
  some_id integer not null,
  month1 integer,
  month2 integer,
  month3 integer,
  month4 integer,
  month5 integer,
  month6 integer,
  month7 integer,
  month8 integer,
  month9 integer,
  month10 integer,
  month11 integer,
  month12 integer,
  year integer not null,
  primary key(some_id, year)
);

Мы можем создать представление, чтобы превратить его в some_id, дату и данные.

create view good_schema as (
  select 
    some_id,
    cast(concat(year, '-', months.value, '-', '01') as date) as this_month,
    case months.value
    when 1 then month1
    when 2 then month2
    when 3 then month3
    when 4 then month4
    when 5 then month5
    when 6 then month6
    when 7 then month7
    when 8 then month8
    when 9 then month9
    when 10 then month10
    when 11 then month11
    when 12 then month12
    else 'what'
    end as data
  from bad_schema
  cross join (
    select * from generate_series(1, 12)
  ) as months
)

Затем мы можем запросить это обычными способами.

select * from good_schema

some_id     this_month  data
1           2023-01-01  1
1           2023-02-01  2
1           2023-03-01  3
1           2023-04-01  4
1           2023-05-01  5
1           2023-06-01  6
1           2023-07-01  7
...etc...

select sum(data) 
from good_schema
where this_month between '2023-01-01' and '2023-05-01'
group by some_id

Демонстрация.

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

Другие вопросы по теме