Я пишу следующий сценарий SQL и обнаружил ошибку, указанную непосредственно под указанным сценарием:
SELECT
concat(month([sbi].[dtmDelivered]),'-',year([sbi].[dtmDelivered])) as rdate
,o.[strCompanyNodeName]
,sum(sbi.[mnyDollarcost])
,p.[strProductName]
,p.[strProductType]
,o.[strSalesRegionNodeGroup]
,o.[strSalesRegionNodeName]
,concat(o.[strMasterSalesFirstNameNode],' ',o.[strMasterSalesLastNameNode]) AS "Sales_Rep" FROM [sqlSalesBI].[Fact].[uvwReport] as "sbi"
LEFT JOIN [sqlDim].[dbo].[tbldimProduct] as "p" ON [sbi].[intDimProductPrimaryID] = p.intDimProductID
LEFT JOIN [sqlSalesBI].[Dim].[uvwOrgNode] as "o" ON [sbi].[intOrgNodeID] = o.intOrgNodeID
LEFT JOIN [sqlDim].[dbo].[tbldimStatus] as "t" ON [sbi].[intDimStatusID] = t.intDimStatusID
WHERE sbi.intDimStatusID = 5 and sbi.mnyDollarcost >0 and sbi.dtmDelivered >= '2015-01-01 00:00:00.000'
GROUP BY o.strCompanyNodeName
ОШИБКА ПОЛУЧАЮ ПРИ ВЫПОЛНЕНИИ
Msg 8120, Level 16, State 1, Line 3
Column 'sqlSalesBI.Fact.uvwReport.dtmDelivered' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Msg 8120, Level 16, State 1, Line 3
Column 'sqlSalesBI.Fact.uvwReport.dtmDelivered' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
В конечном итоге я надеюсь получить конечную таблицу, в которой выручка ('mnydollarcost') суммируется и сгруппирована по месяцам и годам ('rdate'), а также по компаниям ('strCompanyNodeName').
Вот таблица, демонстрирующая, каким я хотел бы получить результат
rdate strcompanynodename Sum of MnyDollar Cost other columns >>>
----------------------------------------------------------------------------------
7-2017 Chadwick Supply Co. 5100
7-2017 Northeastern Milling 5600
7-2017 Ford Paper 25320
7-2017 Cleveland Paper Co. 1020
8-2017 Chadwick Supply Co. 1200
8-2017 Northeastern Milling 5600
8-2017 Ford Paper 58450
8-2017 Cleveland Paper Co. 1200
Я новичок в SQL, поэтому заранее благодарим вас за терпение!
Если вы не агрегируете поле с помощью формулы агрегирования (sum(), max() и т. д.) В предложении SELECT, тогда оно ДОЛЖНО присутствовать в GROUP BY. Добавьте эти столбцы в свой пункт GROUP BY и повторите отправку.
Итак, в ответ на ваш первый комментарий я добавил в свою группу по утверждениям. Теперь он гласит: GROUP BY o. [StrCompanyNodeName], p. [StrProductName], p. [StrProductName], p. [StrProductType], o. [StrSalesRegionNodeGroup], o. [StrSalesRegionNodeName], 'rsales_rep' But все еще получаю ошибку: Msg 164, Level 15, State 1, Line 16 Каждое выражение GROUP BY должно содержать по крайней мере один столбец, который не является внешней ссылкой. @LukStorms
@LukStorms Я поймал это примерно через 2 секунды после отправки и удалил свой комментарий.
@James Вместо использования псевдонимов, таких как rdate, используйте настоящее имя в группе by. например sbi.dtmDelivered.
@LukStorms Святое дерьмо, это сработало, так как мой запрос выполняется без проблем. Итак, урок группы по состоит в том, чтобы никогда не использовать псевдонимы для операторов group by? Похоже, это может быть запутанным / трудным для понимания.
Кстати, вам не нужно цитировать каждое имя с помощью [] или ". Если имя не содержит пробелов и не является ключевым словом, можно оставить их без кавычек. Хотя иногда это тоже дело вкуса.
@ Джеймс, я согласен. И я думаю, что в некоторых реляционных базах данных разрешено использовать псевдонимы в группе by. Не в MS SQL. Если вам действительно нужно сгруппировать по псевдониму, вы можете поместить запрос в подзапрос. А затем сгруппируйте по этому псевдониму во внешнем запросе.
Хм, хорошо. Принято к сведению. Итак, запрос завершен, и он выглядит великолепно! НО заголовок для этого столбца rdate читает «без имени столбца», что немного эстетично. Как бы переименовать без псевдонима?
@James Вы можете дать ему псевдоним. Только не используйте этот псевдоним в группе по. например select bar * 10 as bar10, count(*) from foo group by bar в порядке. Но select bar * 10 as bar10, count(*) from foo group by bar10 не работает.
@lukstorms понял!


Похоже, ваш запрос не агрегируется. Добавьте эти недостающие столбцы в свой ГРУППА ПО stmt, и он должен работать здесь.
Формула агрегирования работает как - поле в предложении SELECT, тогда оно ДОЛЖНО присутствовать в GROUP BY.
Как вы уже поняли, в GROUP BY не хватает нескольких:
...
GROUP BY
year(sbi.dtmDelivered),
month(sbi.dtmDelivered),
o.strCompanyNodeName,
p.strProductName,
p.strProductType,
o.strSalesRegionNodeGroup,
o.strSalesRegionNodeName,
o.strMasterSalesFirstNameNode,
o.strMasterSalesLastNameNode;
@James Обратите внимание, что группа не на sbi.dtmDelivered, а на году и месяце. Потому что я предполагаю, что вы захотите сгруппировать по году и месяцу, а не по дате.
Упрощенный фрагмент теста, чтобы понять разницу: declare @T table (dt datetime); insert into @T values (GETDATE()),(GETDATE()-0.01); select year(dt)*100+month(dt) as yyyymm, count(*) as total from @T group by dt; select year(dt)*100+month(dt) as yyyymm, count(*) as total from @T group by year(dt), month(dt);
На самом деле это действительно просто. Если вы не подключаетесь к MySql, когда используется GROUP BY, тогда выбранные вами поля, которые не используются в агрегатной функции (SUM, MAX, COUNT, ...), также должны быть перечислены в GROUP BY.