Запросы для создания базового отчета о пороговом анализе в MS Access - PullRequest
0 голосов
/ 01 марта 2019

В моей попытке создать отчет MS Access для базового анализа пороговых значений я создал 3 последовательных запроса.Производительность ужасна, учитывая, насколько они неэффективны, и я также не получаю ожидаемых результатов от окончательного запроса (объяснено ниже).Будем очень благодарны за любые предложения по очистке.

Первый запрос (Day_Period_Bins_qry1) выполняется как посещенный и суммирует мои данные в различные «корзины» дневного периода, которые построены в обратном порядке от даты, введенной в форму.(Main_frm! Date_prompt_txt).Запрос (ниже) является чрезвычайно тупым, но это то, что я понял

'Category' as N_group, 
Data_tbl.Item_Category as Item, 
Sum(IIf([Data_tbl].[occ_date]<=[Forms]![Main_frm]![Date_prompt_txt] And [Data_tbl].[occ_date]>=DateAdd("d",-6,[Forms]![Main_frm]![Date_prompt_txt]),1,Null)) AS 7Day_Curnt, 
Sum(IIf([Data_tbl].[occ_date]<=DateAdd("d",-7,[Forms]![Main_frm]![Date_prompt_txt]) And [Data_tbl].[occ_date]>=DateAdd("d",-13,[Forms]![Main_frm]![Date_prompt_txt]),1,Null)) AS 7Day_1, 
Sum(IIf([Data_tbl].[occ_date]<=DateAdd("d",-14,[Forms]![Main_frm]![Date_prompt_txt]) And [Data_tbl].[occ_date]>=DateAdd("d",-20,[Forms]![Main_frm]![Date_prompt_txt]),1,Null)) AS 7Day_2, 
Sum(IIf([Data_tbl].[occ_date]<=DateAdd("d",-21,[Forms]![Main_frm]![Date_prompt_txt]) And [Data_tbl].[occ_date]>=DateAdd("d",-27,[Forms]![Main_frm]![Date_prompt_txt]),1,Null)) AS 7Day_3, 
Sum(IIf([Data_tbl].[occ_date]<=DateAdd("d",-28,[Forms]![Main_frm]![Date_prompt_txt]) And [Data_tbl].[occ_date]>=DateAdd("d",-34,[Forms]![Main_frm]![Date_prompt_txt]),1,Null)) AS 7Day_4, 
Sum(IIf([Data_tbl].[occ_date]<=[Forms]![Main_frm]![Date_prompt_txt] And [Data_tbl].[occ_date]>=DateAdd("d",-27,[Forms]![Main_frm]![Date_prompt_txt]),1,Null)) AS 28Day_Curnt, 
Sum(IIf([Data_tbl].[occ_date]<=DateAdd("d",-28,[Forms]![Main_frm]![Date_prompt_txt]) And [Data_tbl].[occ_date]>=DateAdd("d",-55,[Forms]![Main_frm]![Date_prompt_txt]),1,Null)) AS 28Day_1, 
Sum(IIf([Data_tbl].[occ_date]<=DateAdd("d",-56,[Forms]![Main_frm]![Date_prompt_txt]) And [Data_tbl].[occ_date]>=DateAdd("d",-83,[Forms]![Main_frm]![Date_prompt_txt]),1,Null)) AS 28Day_2, 
Sum(IIf([Data_tbl].[occ_date]<=DateAdd("d",-84,[Forms]![Main_frm]![Date_prompt_txt]) And [Data_tbl].[occ_date]>=DateAdd("d",-111,[Forms]![Main_frm]![Date_prompt_txt]),1,Null)) AS 28Day_3, 
Sum(IIf([Data_tbl].[occ_date]<=DateAdd("d",-112,[Forms]![Main_frm]![Date_prompt_txt]) And [Data_tbl].[occ_date]>=DateAdd("d",-139,[Forms]![Main_frm]![Date_prompt_txt]),1,Null)) AS 28Day_4, 
Sum(IIf([Data_tbl].[occ_date]<=[Forms]![Main_frm]![Date_prompt_txt] And [Data_tbl].[occ_date]>=DateAdd("d",-83,[Forms]![Main_frm]![Date_prompt_txt]),1,Null)) AS 84Day_Curnt, 
Sum(IIf([Data_tbl].[occ_date]<=DateAdd("d",-84,[Forms]![Main_frm]![Date_prompt_txt]) And [Data_tbl].[occ_date]>=DateAdd("d",-167,[Forms]![Main_frm]![Date_prompt_txt]),1,Null)) AS 84Day_1, 
Sum(IIf([Data_tbl].[occ_date]<=DateAdd("d",-168,[Forms]![Main_frm]![Date_prompt_txt]) And [Data_tbl].[occ_date]>=DateAdd("d",-251,[Forms]![Main_frm]![Date_prompt_txt]),1,Null)) AS 84Day_2, 
Sum(IIf([Data_tbl].[occ_date]<=DateAdd("d",-252,[Forms]![Main_frm]![Date_prompt_txt]) And [Data_tbl].[occ_date]>=DateAdd("d",-335,[Forms]![Main_frm]![Date_prompt_txt]),1,Null)) AS 84Day_3, 
Sum(IIf([Data_tbl].[occ_date]<=DateAdd("d",-336,[Forms]![Main_frm]![Date_prompt_txt]) And [Data_tbl].[occ_date]>=DateAdd("d",-419,[Forms]![Main_frm]![Date_prompt_txt]),1,Null)) AS 84Day_4, 
Sum(IIf([Data_tbl].[occ_date]<=[Forms]![Main_frm]![Date_prompt_txt] And [Data_tbl].[occ_date]>=DateAdd("d",-363,[Forms]![Main_frm]![Date_prompt_txt]),1,Null)) AS 364Day_Curnt, 
Sum(IIf([Data_tbl].[occ_date]<=DateAdd("d",-364,[Forms]![Main_frm]![Date_prompt_txt]) And [Data_tbl].[occ_date]>=DateAdd("d",-727,[Forms]![Main_frm]![Date_prompt_txt]),1,Null)) AS 364Day_1, 
Sum(IIf([Data_tbl].[occ_date]<=DateAdd("d",-728,[Forms]![Main_frm]![Date_prompt_txt]) And [Data_tbl].[occ_date]>=DateAdd("d",-1091,[Forms]![Main_frm]![Date_prompt_txt]),1,Null)) AS 364Day_2, 
Sum(IIf([Data_tbl].[occ_date]<=DateAdd("d",-1092,[Forms]![Main_frm]![Date_prompt_txt]) And [Data_tbl].[occ_date]>=DateAdd("d",-1455,[Forms]![Main_frm]![Date_prompt_txt]),1,Null)) AS 364Day_3, 
Sum(IIf([Data_tbl].[occ_date]<=DateAdd("d",-1456,[Forms]![Main_frm]![Date_prompt_txt]) And [Data_tbl].[occ_date]>=DateAdd("d",-1819,[Forms]![Main_frm]![Date_prompt_txt]),1,Null)) AS 364Day_4
FROM Data_tbl
GROUP BY Data_tbl.Item_Category

Есть два других запроса, объединенных с вышеупомянутым запросом, которые запрашивают item_type и item_category.

Второй запрос (Columns_qry2) помещает данные из вышеупомянутого запроса в столбцы, чтобы третий столбец мог выполнить некоторые вычисления

Select

N_group,
Item,
nz([7Day_Curnt],0) as nCount,
'7Day' as Day_Period,
'Current' as Day_bin

FROM Day_Period_Bins_qry1


UNION ALL

Select
N_group, 
Item,
Nz( [7Day_1],0) as nCount,
'7Day' as Day_Period,
'1' as Day_bin

FROM Day_Period_Bins_qry1

UNION ALL 

SELECT N_group, 
Item,  
Nz( [7Day_2],0) as nCount,
'7Day' as Day_Period,
'2' as Day_bin


FROM Day_Period_Bins_qry1

UNION ALL

SELECT 
N_group, 
Item, 
 Nz( [7Day_3],0) as nCount,
'7Day' as Day_Period,
'3' as Day_bin


FROM Day_Period_Bins_qry1


UNION ALL 

SELECT N_group, 
Item, 
 Nz( [7Day_4],0) as nCount,
'7Day' as Day_Period,
'4' as Day_bin

FROM Day_Period_Bins_qry1

UNION ALL

Select

N_group,
Item,
nz([28Day_Curnt],0) as nCount,
'28Day' as Day_Period,
'Current' as Day_bin

FROM Day_Period_Bins_qry1

UNION ALL

SELECT 
N_group, 
Item,
Nz( [28Day_1],0) as nCount,
'28Day' as Day_Period,
'1' as Day_bin

FROM Day_Period_Bins_qry1

UNION ALL 

SELECT 
N_group, Item,  
Nz( [28Day_2],0) as nCount,
'28Day' as Day_Period,
'2' as Day_bin


FROM Day_Period_Bins_qry1

UNION ALL

SELECT
 N_group, Item,  
Nz( [28Day_3],0) as  nCount,
'28Day' as Day_Period,
'3' as Day_bin

FROM Day_Period_Bins_qry1


UNION ALL

 SELECT 
N_group, Item,
  Nz( [28Day_4],0) as nCount,
'28Day' as Day_Period,
'4' as Day_bin


FROM Day_Period_Bins_qry1


UNION ALL

Select

N_group,
Item,
nz([84Day_Curnt],0) as nCount,
'84Day' as Day_Period,
'Current' as Day_bin

FROM Day_Period_Bins_qry1


Union All

SELECT 
N_group, 
Item,
Nz( [84Day_1],0) as nCount,
'84Day' as Day_Period,
'1' as Day_bin

FROM Day_Period_Bins_qry1

UNION ALL 

SELECT N_group, 
Item, 
 Nz( [84Day_2],0) as nCount,
'84Day' as Day_Period,
'2' as Day_bin

FROM Day_Period_Bins_qry1

UNION ALL

SELECT 
N_group, Item, 
 Nz( [84Day_3],0) as  nCount,
'84Day' as Day_Period,
'3' as Day_bin

FROM Day_Period_Bins_qry1


UNION ALL 
SELECT N_group, 
Item,  Nz( [84Day_4],0) as nCount,
'84Day' as Day_Period,
'4' as Day_bin


FROM Day_Period_Bins_qry1


UNION ALL

Select

N_group,
Item,
nz([364Day_Curnt],0) as nCount,
'364Day' as Day_Period,
'Current' as Day_bin

FROM Day_Period_Bins_qry1



Union All

SELECT 
N_group, 
Item,
Nz( [364Day_1],0) as nCount,
'364Day' as Day_Period,
'1' as Day_bin

FROM Day_Period_Bins_qry1

UNION ALL 

SELECT N_group, Item, 
 Nz( [364Day_2],0) as Count,
'364Day' as Day_Period,
'2' as Day_bin

FROM Day_Period_Bins_qry1

UNION ALL

SELECT 
N_group, Item, 
 Nz( [364Day_3],0) as  nCount,
'364Day' as Day_Period,
'3' as Day_bin

FROM Day_Period_Bins_qry1


UNION ALL SELECT N_group, Item,  
Nz( [364Day_4],0) as nCount,
'364Day' as Day_Period,
'4' as Day_bin


FROM Day_Period_Bins_qry1;

Последний запрос не завершен и находится на третьей или четвертой итерации.В настоящее время у меня возникают проблемы с выяснением того, как заставить столбцы выполнять вычисления только в одном и том же дневном периоде (т. Е. Рассчитывать только среднее для бинов [7day] для сравнения с текущим 7-дневным счетчиком. Ранее было добавлено простое предложение where (гдеday_bin = '7day) и повторяется в запросах объединения для других дневных периодов, что дало бы мне требуемые результаты, но при добавлении еще одного запроса объединения был журнал, который сломал верблюдов, вызвав сбой.

SELECT 
Columns_qry2.N_group AS N_group, 
Columns_qry2.item AS Item, 
Columns_qry2.Day_period, 
Columns_qry2.nCount AS Current_Ct, 
Round(Avg(Columns_qry2.[nCount]),2) AS Avg_Prev4_Bins,
 Round((Day_Period_bins_qry1.[7Day_Curnt]-[Avg_Prev4_Bins])/StDevP([nCount]),2) AS Z_score, 
Round((Day_Period_bins_qry1.[7Day_Curnt]-Avg([nCount]))/Avg([nCount]),2) AS PercentChg_From_BinAvg_Prev4Bins, 
Round(Day_Period_Bins_qry1.[7Day_Curnt]/(Select SUM(Day_Period_Bins_qry1.[7Day_Curnt]) FROM Day_Period_Bins_qry1),2) AS Percent_of_Total_Current, 
Round(Avg(Day_Period_bins_qry1.[7Day_1]/(Select SUM(Day_Period_bins_qry1.[7Day_1]) FROM Day_Period_bins_qry1)+Day_Period_bins_qry1.[7Day_2]/(Select SUM(Day_Period_bins_qry1.[7Day_2]) FROM Day_Period_bins_qry1)+Day_Period_bins_qry1.[7Day_3]/(Select SUM(Day_Period_bins_qry1.[7Day_3]) FROM Day_Period_bins_qry1)+Day_Period_bins_qry1.[7Day_4]/(Select SUM(Day_Period_bins_qry1.[7Day_4]) FROM Day_Period_bins_qry1))/4,2) AS Avg_Percent_of_Tot_prev4_Bins, 
Round(([Percent_of_Total_Current]-Avg_Percent_of_Tot_prev4_Bins)/Avg_Percent_of_Tot_prev4_Bins,4) AS PercentChg_Percent_of_Total

FROM Columns_qry2 
INNER JOIN Day_Period_bins_qry1 
ON Day_Period_bins_qry1.item =  Columns_qry2.Item

GROUP BY Columns_qry2.N_group, Columns_qry2.item, Columns_qry2.Day_period, Columns_qry2.nCount, Day_Period_bins_qry1.[7Day_Curnt];

1 Ответ

0 голосов
/ 01 марта 2019

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

Таблица (myDateRangeTable)

Start_Num  End_Num   Day_Period   Day_Bin
0          -6        '7Day'       'Curnt'     
-7         -13       '7Day'       '1'     
-14        -20       '7Day'       '2'     
-21        -27       '7Day'       '3'     
-28        -34       '7Day'       '4'     
0          -27       '28Day'      'Curnt'     
-28        -55       '28Day'      '1'     
-56        -83       '28Day'      '2'     
-84        -111      '28Day'      '3'     
-112       -139      '28Day'      '4'     
0          -83       '84Day'      'Curnt'     
-84        -167      '84Day'      '1'     
-168       -251      '84Day'      '2'     
-252       -335      '84Day'      '3'     
-336       -419      '84Day'      '4'     
0          -363      '364Day'     'Curnt'     
-364       -727      '364Day'     '1'     
-728       -1091     '364Day'     '2'     
-1092      -1455     '364Day'     '3'     
-1456      -1819     '364Day'     '4'

Базовый запрос 1

Ниже приведено перекрестное объединение с исходной таблицей данных для сопоставления каждомукомбинация строки таблицы данных с указанными выше вариантами.Затем подсчитывает любые совпадения диапазона дат.Если исходная таблица очень большая, обработка может занять некоторое время.Рассмотрим , сделав его временной таблицей , если это так, добавив INTO [myTempTable] непосредственно перед FROM.Ниже следует повторить ваш запрос на объединение.

SELECT 'Category' as N_group, 
        d.Item_Category as Item, 
        m.Day_Period,
        m.Day_Bin,
        SUM(d.[occ_date] BETWEEN DateAdd("d", m.Start_Num, [Forms]![Main_frm]![Date_prompt_txt]) 
                             AND DateAdd("d", m.End_Num, [Forms]![Main_frm]![Date_prompt_txt])
           ) AS Date_Count
FROM Data_tbl d,
     myDateRangeTable m
GROUP BY d.Item_Category,
         m.Day_Period,
         m.Day_Bin;

Окончательный запрос (myFinalQuery)

Ниже приведен неполный запрос, объединяющий уровень единицы и агрегатуровни по Day_Period .Рассмотрите возможность корректировки для необходимых формул.Остальные проблемы заключаются в том, чтобы вычислить поля в строках для разных значений Day_Bin.Для этого может потребоваться вложенное выражение IIF или присоединение к кросс-таблице 1035 *.Обратите внимание, что скобки требуются для нескольких объединений в диалекте SQL MS Access.

SELECT
  b.N_Group,
  b.Item,
  b.Day_Period,
  b.Day_Bin,
  Round((b.[Day_Count] - agg1.[Avg_Prev4_Bins]) / agg1.Std_Prev4_Bins, 2) 
       AS Z_score, 
  Round((b.[Day_Count] - agg1.[Avg_Prev4_Bins])) / b.[Day_Count], 2) 
       AS PercentChg_From_BinAvg_Prev4Bins, 
  Round(IIF(b.Day_Bin = 'Current', b.[Day_Count] / agg2.curr_SumDayCount,
            IIF(b.Day_Bin = '1',  b.[Day_Count] / agg2.d1_SumDayCount,
                IIF(b.Day_Bin = '2',  b.[Day_Count] / agg2.d2_SumDayCount, 
                    IIF(b.Day_Bin = '3',  b.[Day_Count] / agg2.d3_SumDayCount,
                        IIF(b.Day_Bin = '4',  b.[Day_Count] / agg2.d4_SumDayCount, NULL)
                        )
                   )
               )
           ), 
       2) AS Percent_of_Total, 
  ...
FROM
 ((myBaseQuery AS b
INNER JOIN
     (SELECT Day_Period, 
             AVG(Day_Count) AS Avg_Prev4_Bins,
             StDevP([Day_Count]) AS Std_Prev4_Bins
      FROM myBaseQuery 
      GROUP BY Day_Period) AS agg1
   ON agg1.Day_Period = b.Day_Period)

INNER JOIN
     (SELECT Day_Period, 
             SUM(IIF(Day_Bin = 'Current', Day_Count, NULL)) AS curr_SumDayCount, 
             SUM(IIF(Day_Bin = '1', Day_Count, NULL)) AS d1_SumDayCount,
             SUM(IIF(Day_Bin = '2', Day_Count, NULL)) AS d2_SumDayCount,
             SUM(IIF(Day_Bin = '3', Day_Count, NULL)) AS d3_SumDayCount,
             SUM(IIF(Day_Bin = '4', Day_Count, NULL)) AS d4_SumDayCount  
      FROM myBaseQuery 
      GROUP BY Day_Period) AS agg2
   ON agg2.Day_Period = b.Day_Period)

Запрос кросс-таблицы

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

TRANSFORM SUM(Day_Count) AS SumDayCount
SELECT Day_Period
FROM myBaseQuery
GROUP BY Day_Period
PIVOT Day_Bin IN ([Curnt], [1], [2], [3], [4])

Надеемся, что некоторая часть выше полезна!

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