简体   繁体   中英

SQL Server Subquery Error - The Multi-Part Identifier Could Not Be Bound

I am trying to extract the top 50 sku's by gross $ from a table containing invoice data. I am using 2 nested subqueries. The first two subqueries generate the expected result when run separately. When I add the last query, I get the following 2 errors:

Msg 4104, Level 16, State 1, Line 1
The multi-part identifier "a.year_month" could not be bound.

Msg 4104, Level 16, State 1, Line 3
The multi-part identifier "a.keycust3" could not be bound.

See the query below:

SELECT 
    a.year_month
    ,b.part_number
    ,a.keycust3
    ,SUM(b.gross3) AS gross4
 FROM
     (SELECT TOP (50) 
          a.part_number
          ,SUM(a.gross2) AS gross3
      FROM
          (SELECT  
               year_month AS yr_mnth
               ,part_number
               ,keycust3
               ,yr
               ,SUM(gross) AS gross2
           FROM 
               AWS_Stage
           GROUP BY 
               year_month, part_number, keycust3, yr) AS a
      WHERE  
          yr = 2019
      GROUP BY 
          part_number/*,
      ORDER BY 
          gross2 DESC*/
      ) AS b

a Is not available at the top level of your select; it was lost at the moment b was created. If you want to reference columns in a , the subquery b would have to select them and then you call them b.whatever . Because you're grouping you might not realistically be able do this because when you select them at the level of b you'll either have to add them to the group by (in which case they will cause subdivisions of the group) or add them as an aggregate (in which case they will become mixed with other row values an no longer represent), so you'll have to join the table again at the outer level.

I'm not really sure what the double grouping you have is achieving because it groups and sums then filters and groups and sums again. If you had this:

A,B,C
X,Y,2
X,Y,3
X,Z,4
A,B,1

And you group by A,B, summed C then where only X then group by just A and summed again it would go from:

--group by A B
A,B,C
X,Y,5
X,Z,4
A,B,1

To:

--where x
A,B,C
X,Y,5
X,Z,4

To:

--group by a   
A,C
X,9

But you might as well have just WHERE X GROUP BY A SUM C - the first groupby didn't give you anything

The key point here is that, aside from not being able to use columns at an outer level if they weren't selected at an inner level, once you've lost detail in a grouping operation, you can't get it back (it's like huge lossy compression of an image; once degraded it will always look blocky and pixelated no matter what the movies "I need that grey square of a license plate enhanced and readable" tell you); you have to go back to the source data with the detail and join your grouped data onto it via whatever columns you have left as a group

As such I think you can rewrite your query like this:

SELECT 
    *
 FROM
    AWS_Stage a
    INNER JOIN
     (SELECT 
          yr,
          part_number,
          SUM(a.gross) AS sumgross2019
      FROM
          AWS_Stage
      WHERE  
          yr = 2019
      GROUP BY 
          yr, part_number
      ) x
     ON a.yr = x.yr AND a.part_number = x.part_number

But it's kinda hard to know whether this is what you want from "I tried this non working thing" and "top 50 sku" (why is 2019 in the query when the spec didn't say "from last year" etc).

If you're looking for "all of the 2019 detail plus the sum of all the gross per partnumber for 2019" this is it (except for the top 50 part, which I'm sure you can add). It can also be written using a window function..

SELECT 
    *,
    SUM(gross) OVER(PARTITION BY a.part_number) as sumgrossperpartnumber
FROM
    AWS_Stage a
WHERE 
    a.yr = 2019

If you're looking for multi level or multi factor grouping, the window function way there might be simpler. If you want to compare years, move yr out of the where clause and add it into the partition by instead. If you wanted all the detail from all years, but only grossing up from last year you can:

SELECT 
    *,
    SUM(CASE WHEN yr = 2019 THEN gross ELSE 0 END) OVER(PARTITION BY a.part_number) as sumgrossperpartnumber
FROM
    AWS_Stage a

Since your alias a is only valid within the subselect aliased by b the problem is to select a.year_month and a.keycut3 in your main select. b has to deliver these columns as well and then change your main select to

SELECT b.year_month
  ,b.part_number
  ,b.keycust3
  ,SUM(b.gross3) AS gross4

For sure you have to deal with your grouping in b .

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