BikliWe Wiyao ALI Ответов: 3

SQL выберите группу ошибку: поле не содержится в статистической функции или группы by пункт


SELECT a.userName, productType, MAX(TotalSales) 
	FROM(
		SELECT U.Name AS userName, SP.Type AS productType, SUM(SP.Price) AS TotalSales
			FROM [SaleProduct] SP
				JOIN [Sale] S ON SP.SaleId = S.SaleId
					JOIN [User] U ON U.UserId = S.UserId
						GROUP BY SP.Type, U.UserName) AS a
		GROUP BY productType, a.userName
		)


дать мне

Name| Product-Type | Sales
XYZ | Laptops| 999
ABC | Desktop| 888
ABC | Servers|777
XYZ | Servers|555


Я хочу:
Name| Product Type|Sales
XYZ |Laptops| 999
ABC |Desktop| 888
ABC |Servers|777


Если мне нужно только вернуть массив выше ( ABC, имеющий наибольший общий объем продаж серверов), как я должен написать запрос ?
Приведенный ниже запрос работает , ожидайте , что мне все еще нужно вернуть "имя" из внешнего запроса (но, объединив имя и включив его во внешний запрос, он также вернет XYZ с общим объемом продаж 555. Как это сделать ?

Что я уже пробовал:

SELECT productType, MAX(TotalSales) 
	FROM(
		SELECT U.Name AS userName, SP.Type AS productType, SUM(SP.Price) AS TotalSales
			FROM [SaleProduct] SP
				JOIN [Sale] S ON SP.SaleId = S.SaleId
					JOIN [User] U ON U.UserId = S.UserId
						GROUP BY SP.Type, U.Name) AS a
		GROUP BY productType
		)


приведенный выше запрос работает ожидайте что мне все еще нужно вернуть имя из внешнего запроса SELECT
как это сделать ?

Bryian Tan

Что??? не совсем понятно, о чем ваш вопрос и недостаточно информации. Может быть, вы хотите включить столбец "мой" в свой последний запрос?

SELECT my, productType, MAX(TotalSales) 
	FROM(
		SELECT U.UserName AS my, SP.Type AS productType, SUM(SP.Price) AS TotalSales
			FROM [SaleProduct] SP
				JOIN [Sale] S ON SP.SaleId = S.SaleId
					JOIN [User] U ON U.UserId = S.UserId
						GROUP BY SP.Type, U.UserName) AS a
		GROUP BY my, productType

CHill60

Я думаю, что у меня есть решение, которое вам нужно, но серверы сейчас немного заняты. Я попробую еще раз позже

3 Ответов

Рейтинг:
2

BikliWe Wiyao ALI

Предоставленная ссылка не описывает мой вопрос. Можете ли вы дать мне пример кода из моего вопроса, чтобы решить эту проблему

OriginalGriff

Да, это так - он не дает вам код, который, как вы думаете, вам нужен, Но он объясняет, почему вы получаете проблему. А это значит, что как только вы разберетесь с этим, вам не нужно будет спрашивать снова в следующий раз ...

Рейтинг:
0

kmoorevs

Каждое поле в операторе select, для которого вы не выполняете агрегатную функцию (Sum, Avg, Max и т. д.), должно быть указано в предложении Group By. Кроме того, группа By не допускает псевдонимов полей, вы должны использовать там фактическое имя поля.

Если ваш пример работает с подзапросом, все, что вам нужно сделать, это сослаться на псевдоним " Мой " для вашего пользователя во внешнем запросе, а затем не забудьте сгруппироваться по нему.


BikliWe Wiyao ALI

1."каждое поле в вашем операторе select, над которым вы не выполняете агрегатную функцию (Sum, Avg, Max и т. д.), должно быть указано в предложении Group By", которое я понял.
2."группа By не допускает псевдонимов полей, вы должны использовать там фактическое имя поля". поступая таким образом, это дает мне ошибку field not bounded, так как( она находится во внешнем запросе)
3." ... все, что вам нужно сделать, это сослаться на псевдоним " Мой "для вашего пользователя во внешнем запросе, а затем не забудьте сгруппироваться по нему". Как я уже сказал, группировка по "моему" дает мне больше того, что мне нужно вернуть, как в первом массиве. Если я вас не понимаю можете ли вы предложить пример кода

kmoorevs

Извините, я изначально неверно истолковал ваши запросы. Я был сбит с толку дополнительным ) в конце внешнего запроса. Неясно, что вы пытаетесь получить в результате. Лучший продавец по типу продукта? (а как насчет типа продукта 555?)

Рейтинг:
0

CHill60

Другие плакаты подхватывают ваши ошибки в группе, и я попытаюсь ответить на основной вопрос.

Я думать то, что вы пытаетесь сделать, - это просто вернуть имя Пользователя с самым высоким рейтингом, основанное на общем объеме продаж по типу продукта. Самый простой способ сделать это - использовать функцию ROW_NUMBER с PARTITION BY-see ROW_NUMBER (Transact-SQL) | Microsoft Docs[^]

Например:

;with CTE AS
(
	SELECT U.Name AS userName, SP.Type AS productType, SUM(SP.Price) AS TotalSales
	, ROW_NUMBER() OVER (PARTITION BY sp.type ORDER BY SUM(SP.Price) DESC) as rn
	FROM #SaleProduct SP
	LEFT JOIN #Sale S ON SP.SaleId = S.SaleId
	LEFT JOIN #User U ON U.UserId = S.UserId
	GROUP BY SP.Type, U.Name
)
SELECT CTE.* FROM CTE WHERE rn = 1
Я решил использовать общее табличное выражение, поскольку мне легче следовать ему - эквивалент использования подзапроса будет следующим
SELECT * FROM 
(
	SELECT U.Name AS userName, SP.Type AS productType, SUM(SP.Price) AS TotalSales
	, ROW_NUMBER() OVER (PARTITION BY sp.type ORDER BY SUM(SP.Price) DESC) as rn
	FROM #SaleProduct SP
	LEFT JOIN #Sale S ON SP.SaleId = S.SaleId
	LEFT JOIN #User U ON U.UserId = S.UserId
	GROUP BY SP.Type, U.Name
) as a
WHERE rn = 1
Моменты, которые следует отметить:
- Я использовал PARTITION BY, чтобы перезапустить нумерацию внутри каждой "группы" вещей (в данном случае типов продуктов). Если я просто выполню внутренний запрос, то получу следующие результаты:
ABC	Desktop	888.00	1
XYZ	Laptop	999.00	1
ABC	Server	777.00	1
XYZ	Server	555.00	2
Заметить это rn показывает, кто пришел в номер 1, номер 2 и т. д.

Это решение не учитывает связи (т. е. два продавца имеют точно такой же объем продаж для конкретного продукта). Совместные победители! Чтобы удовлетворить этот сценарий, вам было бы лучше использовать ранг - см. Ранг (Transact-SQL) | Microsoft Docs[^]