SQL Ошибка серверного подзапроса - не удалось связать идентификатор из нескольких частей - PullRequest
0 голосов
/ 30 апреля 2020

Я пытаюсь извлечь первые 50 наименований товаров из таблицы брутто из таблицы, содержащей данные счета. Я использую 2 вложенных подзапроса. Первые два подзапроса генерируют ожидаемый результат при запуске отдельно. Когда я добавляю последний запрос, я получаю следующие 2 ошибки:

Сообщение 4104, Уровень 16, Состояние 1, Строка 1
Не может быть многоэлементный идентификатор "a.year_month" bound.

Msg 4104, уровень 16, состояние 1, строка 3
Не удалось связать многоэлементный идентификатор "a.keycust3".

См. запрос ниже :

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

Ответы [ 2 ]

2 голосов
/ 30 апреля 2020

a Недоступно на верхнем уровне вашего выбора; он был потерян в момент создания b. Если вы хотите сослаться на столбцы в a, подзапрос b должен будет выбрать их, а затем вызвать их b.whatever. Поскольку вы группируете, вы не сможете реально сделать это, потому что, когда вы выбираете их на уровне b, вам нужно либо добавить их в группу (в этом случае они вызовут подразделения группы), либо добавьте их как совокупность (в этом случае они будут смешаны с другими значениями строк, которые больше не будут представлять), поэтому вам придется снова присоединиться к таблице на внешнем уровне.

Я не совсем уверен, чего достигла ваша двойная группировка, потому что она группирует и суммирует, затем фильтрует, группирует и суммирует снова. Если бы у вас было это:

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

И вы сгруппировали по A, B, суммировали C, тогда, где только X, затем сгруппировали по просто A и суммировали снова, это было бы go из:

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

Кому:

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

Кому:

--group by a   
A,C
X,9

Но вы могли бы также иметь ГДЕ X ГРУППА ПО СУММЕ C - первая группа не дала вам что угодно

Ключевым моментом здесь является то, что, помимо невозможности использовать столбцы на внешнем уровне, если они не были выбраны на внутреннем уровне, после потери деталей в операции группировки, вы не могу получить его обратно (это похоже на огромное сжатие изображения с потерями; после ухудшения оно всегда будет выглядеть блочным и пиксельным, независимо от того, что говорят фильмы: «Мне нужен улучшенный и читаемый серый квадрат номерного знака»); вам нужно go вернуться к исходным данным с подробной информацией и присоединить к ним ваши сгруппированные данные через любые столбцы, которые вы оставили как группа

Поэтому я думаю, что вы можете переписать свой запрос следующим образом:

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

Но довольно трудно понять, хотите ли вы этого из "Я попробовал эту нерабочую вещь" и "50 лучших sku" (почему 2019 в запросе, когда spe c не сделал скажем "с прошлого года" et c).

Если вы ищете «все детали 2019 года плюс сумму всех брутто на номер детали для 2019 года», то это все (кроме верхней 50 части, которую, я уверен, вы можете добавить) , Это также может быть записано с использованием оконной функции.

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

Если вы ищете многоуровневую или многофакторную группировку, оконная функция может быть проще. Если вы хотите сравнить годы, уберите год из предложения where и вместо этого добавьте его в раздел. Если вам нужны все детали за все годы, но только с прошлого года, вы можете:

SELECT 
    *,
    SUM(CASE WHEN yr = 2019 THEN gross ELSE 0 END) OVER(PARTITION BY a.part_number) as sumgrossperpartnumber
FROM
    AWS_Stage a
0 голосов
/ 30 апреля 2020

Поскольку ваш псевдоним a действителен только для подвыбора с псевдонимом b , проблема заключается в выборе a.year_month и a.keycut3 в вашем основном выборе. b должен также доставить эти столбцы, а затем изменить свой основной выбор на

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

. Вам наверняка придется иметь дело с вашей группировкой в ​​ b .

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