Follow up: Access considers query too complex after normalization

走远了吗. 提交于 2019-12-25 01:13:17

问题


At first, I want to apologize for the n+1st Query-too-complex-question.

Since I've been told that my dtabase deserves normalisation, I tried to do the very same thing with a normalised setup. However, Access complains about a too complex query by now.

What I want to do: Starting point is a query that yields fields Item ID, Difference in attribute 1, Group of attribute 1, Difference in Attribute 2, Group of attribute 2,... (about 10.000 rows, query is just an equijoin of the two datasets to compare). For each attribute, I want to draw a histogram showing the distribution of differences for that attribute. In fact, I want to draw two histograms in one canvas, one of which is constrained to Group = 1.

What I tried:

  • First step was to build a normalisation query (based on unions) which yields columns Item ID, attribute, difference, group. This query yields about 100.000 rows.
  • Next step is to draw the histogram. Unfortunately, access has no built-in histogram chart, so I resorted to a xy-chart whose data source is a query that is a union of four queries that yield the for corners of the bins.
  • Since I want to draw two histograms, this data source query is unioned with a copy of itself that bears the additional group = 1-condition.

So I endet up with the following query:

select bin, max(c), max(c2) from (
    -- collect the four corners of the first histogram
    select bin, cnt as c, 1 as c2, ord from (
        -- top right
        select
            cdbl(bin(difference, 0.1, -2, 2) + 0.05) AS bin,
            Count(bin) AS cnt,
            1 as ord
        FROM normalized_data
        WHERE difference Is Not Null
            and attribut='attibute_name'
            and difference between -2 and 2
        GROUP BY
            cdbl(bin(difference, 0.1, -2, 2) + 0.05)

        union all

        -- bottom right
        select
            cdbl(bin(difference, 0.1, -2, 2) + 0.05) AS bin,
            0 AS cnt,
            2 as ord
        FROM normalized_data
        WHERE difference Is Not Null
            and attribut='attibute_name'
            and difference between -2 and 2
        GROUP BY
            cdbl(bin(difference, 0.1, -2, 2) + 0.05)

        union all

        -- bottom left
        select
            cdbl(bin(difference, 0.1, -2, 2) - 0.05) AS bin,
            0 AS cnt,
            3 as ord
        FROM normalized_data
        WHERE difference Is Not Null
            and attribut='attibute_name'
            and difference between -2 and 2
        GROUP BY
            cdbl(bin(difference, 0.1, -2, 2) - 0.05)

        union all

        -- top left
        select
            cdbl(bin(difference, 0.1, -2, 2) - 0.05) AS bin,
            Count(bin) AS cnt,
            4 as ord
        FROM normalized_data
        WHERE difference Is Not Null
            and attribut='attibute_name'
            and difference between -2 and 2
        GROUP BY
            cdbl(bin(difference, 0.1, -2, 2) - 0.05)
        order by bin, ord asc
    ) 

    union all 

    -- connect the corners of the other one
    select bin, 1 as c, cnt as c2, ord from (
        select
            cdbl(bin(difference, 0.1, -2, 2) + 0.05) AS bin,
            Count(bin) AS cnt,
            1 as ord
        FROM normalized_data
        WHERE difference Is Not Null
            and attribut='attibute_name'
            and difference between -2 and 2
            AND (GR=1)
        GROUP BY
            cdbl(bin(difference, 0.1, -2, 2) + 0.05)
        union all
        select
            cdbl(bin(difference, 0.1, -2, 2) + 0.05) AS bin,
            0 AS cnt,
            2 as ord
        FROM normalized_data
        WHERE difference Is Not Null
            and attribut='attibute_name'
            and difference between -2 and 2
            AND (GR=1)
        GROUP BY
            cdbl(bin(difference, 0.1, -2, 2) + 0.05)
        union all
        select
            cdbl(bin(difference, 0.1, -2, 2) - 0.05) AS bin,
            0 AS cnt,
            3 as ord
        FROM normalized_data
        WHERE difference Is Not Null
            and attribut='attibute_name'
            and difference between -2 and 2
            AND (GR=1)
        GROUP BY
            cdbl(bin(difference, 0.1, -2, 2) - 0.05)
        union all
        select
            cdbl(bin(difference, 0.1, -2, 2) - 0.05) AS bin,
            Count(bin) AS cnt,
            4 as ord
        FROM normalized_data
        WHERE difference Is Not Null
            and attribut='attibute_name'
            and difference between -2 and 2
            AND (GR=1)
        GROUP BY
            cdbl(bin(difference, 0.1, -2, 2) - 0.05)
        order by bin, ord asc
    )
) 
group by bin, ord 
order by bin, ord asc

The two innermost unions are computed, as well as the two queries in the middle level. However, when I try to compute the outermost union, access complains about the query's complexity (which did not happen on the unnormalized query)

Question: Do I have any chance to resolve this?

Remark: The middle step has been introduced to ease automatic code generation. Removal doesn't solve the problem.

Edit: What is in the tables: As requested, I shall add some information about what is stored in tables and what is queried. I am given two tables

create table A (
    id integer not null primary key,
    [attribute 1] integer,
    [attribute 2] integer,
    ...
)

create table B (
    id integer not null primary key,
    [attribute 1] integer,
    [attribute 2] integer,
    ...
)

and a query differences to complare them:

select
    id,
    A.[attribute 1] - B.[attribute 1] as [delta 1],
    ...
from A
inner join B on A.id = B.id

I am aware that this unnormalized data model is bad design, but I am not the person in charge to design the model. This is why a have built a query normalized_data which unpivots the data from differences:

select
    id,
    'attribute 1' as attribute,
    delta 1 as difference
from differences
union all
select
    id,
    'attribute 2' as attribute,
    delta 2 as difference
from differences
union all
...

Note that the code for the query in question above does not change very much if one uses the unnormalized data from differences as input, or the unpivoted data from normalized_data.

来源:https://stackoverflow.com/questions/49317534/follow-up-access-considers-query-too-complex-after-normalization

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!