简体   繁体   中英

Can't find error with MS Access SQL FROM Clause Syntax

Select distinct [Doc Type], [Customer Number], count([Customer Number]) , [T] From (
Select distinct A.[Customer Number] & A.[Membership Number], A.[Customer Number] , B.[Doc Type ], B.[SumOpenAmount] From(
SELECT distinct [Doc Type] , [Customer Number], Sum([Open Amount]) as T  FROM Data Where [Doc Type] = 'RU')B, [Data] A
Where B.[Customer Number] = A.[Customer Number] Group by [Doc Type]) 
group by [Doc Type], [Customer Number]
having count([Customer Number]) = 1

Throwing an Error that Doc Type could refer to more than 1 table listed in the from clause of your SQL Statement

Currently, your query has a number of syntax and suboptimal issues:

  1. GROUP BY : In aggregate queries that contain non-aggregated columns in SELECT clause, GROUP BY must be used. Some dialects allow GROUP BY columns to be omitted but not Access SQL. Also, DISTINCT is not necessary for GROUP BY .

  2. ALIASES : Whenever subqueries and joins are utilized, always use table aliases to avoid name collision for both derived tables and column aliases for all expressions. Additionally, avoid A, B, C... for more informative aliases including T. See Bad Habits to Kick: Using table aliases like (a, b, c) or (t1, t2, t3) .

  3. EXPLICIT JOIN : Use the current ANSI SQL standard of explicit joins and not the outdated implicit joins that use WHERE . See Explicit vs implicit SQL joins .

Therefore, consider following adjustments that employ the above guidelines.

SELECT [doc type]
     , [customer number]
     , COUNT([customer number]) As CountCustomerNumber          -- ALIAS ADDED
     , SUM([SumOpenAmount]) As TotalOpenAmount                  -- AGGREGATED COLUMN
FROM   
      (SELECT d.[customer number] & d.[membership number] AS CustMemb  -- ALIAS ADDED
            , d.[customer number]
            , agg.[doc type]
            , SUM(agg.[TotalSubOpenAmount]) AS SumOpenAmount    -- AGGREGATED COLUMN
        FROM  (SELECT [doc type]
                    , [customer number]
                    , SUM([open amount]) AS TotalSubOpenAmount  -- INFORMATIVE ALIAS
               FROM   data
               WHERE  [doc type] = 'RU'
               GROUP BY [doc type]
                      , [customer number]
              ) agg                                             -- INFORMATIVE ALIAS
        INNER JOIN [data] d                                     -- INNER JOIN USED
           ON  d.[customer number] = agg.[customer number]
        GROUP  BY d.[customer number] & d.[membership number]   -- GROUP BY COLUMNS ADDED
                , d.[customer number]
                , agg.[doc type]
      ) AS sub                                                  -- ALIAS ADDED
GROUP  BY [doc type]
        , [customer number]
HAVING COUNT([customer number]) = 1 

Note : Since Access does not support comments in queries. Remove all -- messages before running.

So, this is a good reason to do aliasing . I think what's happening is your innermost ( data ) subquery is returning doctype (becomes b as part of the outer subquery), and a also has a doc type . You can also remove the inner Group By clause, because it's done on the outermost query; the results should be the same.

I also noticed that you do this: A.[Customer Number] & A.[Membership Number] and then don't do anything with the column. If you want to do something with that, you should name the Column. I named it CMN below, you can pick whatever you want.

Am I correct that you're also doing an implicit JOIN with the line ) as B, [Data] A ? If so, you should consider making that explicit, or you may end up with undesired matches.

If that's what you want, do this:

-- as B, [Data] A
++ as B LEFT JOIN [Data] as A on a.[Customer Number] = b.[Customer Number]

This way, you can get rid of your Where B.[Customer Number] = A.[Customer Number] line (after testing, of course), and you'll end up with a more explicitly defined JOIN . See bottom for what that looks like.

The first Group by [Doc Type] is what's tripping you up.

When referring to fields, it's my personal preference to always add an alias unless I'm only working with a simple oneliner, with one table/view, even if there aren't any fields with similar names, because I usually end up with duplicate names in the future. Even then, I try to add aliases, because then later if I decide I want to add more fields/tables it doesn't make me re-factor the whole thing.

Try this (if you're not doing implicit JOIN ):

Select distinct c.[Doc Type], c.[Customer Number], c.CMN, count(c.[Customer Number]) , c.[T] 
From (
    Select distinct (A.[Customer Number] & A.[Membership Number]) as CMN, A.[Customer Number] , B.[Doc Type], B.[SumOpenAmount] 
    From(
        SELECT distinct d.[Doc Type] , d.[Customer Number], Sum(d.[Open Amount]) as T  
        FROM Data as d
        Where d.[Doc Type] = 'RU'
        ) as B, [Data] A
    Where B.[Customer Number] = A.[Customer Number] 
    ) as C
group by C.[Doc Type], C.[Customer Number], C.CMN
having count(C.[Customer Number]) = 1

Do this if you want to have an explicit JOIN (recommended):

Select distinct c.[Doc Type], c.[Customer Number], c.CMN, count(c.[Customer Number]) , c.[T] 
From (
    Select distinct (A.[Customer Number] & A.[Membership Number]) as CMN, A.[Customer Number] , B.[Doc Type], B.[SumOpenAmount] 
    From(
        SELECT distinct d.[Doc Type] , d.[Customer Number], Sum(d.[Open Amount]) as T  
        FROM Data as d
        Where d.[Doc Type] = 'RU'
        ) as B 
    LEFT JOIN [Data] as A on a.[Customer Number] = b.[Customer Number]
    ) as C
group by C.[Doc Type], C.[Customer Number], C.CMN
having count(C.[Customer Number]) = 1

(Removed extra spaces)

It appears that the B.[DOC TYPE ] in the sub-query has an extra space in the field name. Also, the sub-query does not reference the inner sub-query's [T] field and as such it will not be available to the main query unless it is in the Data table.
Finally, the outer sub-query's group by does not specify which data source the [Doc Type] is coming from for the grouping.

Try this

Select distinct 
    [Doc Type], 
    [Customer Number], 
    count([Customer Number]), 
    [T] 
From 
    (
        Select 
            distinct A.[Customer Number] & A.[Membership Number], 
            A.[Customer Number] , 
            B.[Doc Type], 
            B.[T] 
        From
            (
                SELECT distinct 
                    [Doc Type] , 
                    [Customer Number], 
                    Sum([Open Amount]) as T  
                FROM 
                    Data 
                Where [Doc Type] = 'RU'
            )B, 
            [Data] A
        Where B.[Customer Number] = A.[Customer Number] 
        Group by B.[Doc Type]
    ) 
group by [Doc Type], [Customer Number]
having count([Customer Number]) = 1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM