Как использовать предложение Group By, когда мы используем функцию Aggregate в объединениях? - PullRequest
7 голосов
/ 21 июня 2011

Я хочу объединить три таблицы и рассчитать сумму (количество) таблицы А. Я попробовал что-то, и я получил желаемый результат. Но все же у меня путаница, основанная на статистической функции и предложении Group By.

При вычислении значения суммы путем объединения двух или более таблиц, какие столбцы мы должны упомянуть в предложении Group By и зачем нам нужно указывать эти столбцы?

Например: вот моя таблица и требуемый запрос.

TableA: ItemID, JobOrderID, CustomerID, DivisionID, Quantity
TableB: ItemID, ItemName, SpecificationID
TableC: SpecificationID, SpecificationName
TableD: DivisionID, DivisionName
TableE: JobOrderID, JobOrderNo.
TableF: CustomerID, CustomerName

Я хочу получить сумму (количество) на основе ItemID, CustomerID, JobOrderID и DivisionID.

Я написал следующий запрос, и он работает нормально. Но если я удалю какой-либо столбец в предложении Group By, он не даст желаемого результата. Зачем? Что здесь делает предложение Group By? Как указать предложение Group By при использовании функции Aggregate? Вот мой запрос.

    SELECT 
            B.ItemName + ' - ' + C.SpecificationName AS 'ItemName',
            SUM(A.Quantity) AS 'Quantity',
            A.ItemID,
            D.DivisionName,
            F.CustomerName,
            E.JobOrderNo,
            A.DivisionID,
            A.JobOrderID,
            A.CustomerID

    FROM
            TableA A  
            INNER JOIN TableB B ON B.ItemID = A.ItemID 
            INNER JOIN TableC C ON C.SpecificationID = B.SpecificationID
            INNER JOIN TableD D ON D.DivisionID = A.DivisionID
            LEFT JOIN TableE E ON E.JobOrderID = A.JobOrderID
            LEFT JOIN TableF F ON F.CustomerID = A.CustomerID
    WHERE
            A.ItemID = @ItemID
    GROUP BY
            A.ItemID,
            A.JobOrderID,
            A.DivisionID,
            A.CustomerID,
            D.DivisionName,
            F.CustomerName,
            E.JobOrderNo,
            B.ItemName,
            C.SpecificationName

Любой, пожалуйста, дайте предложение о предложении Group By, рассмотрев это в качестве примера.

Ответы [ 3 ]

8 голосов
/ 21 июня 2011

GROUP BY для любой уникальной комбинации указанных столбцов агрегирует (например, сумма, мин и т. Д.). Если вы не укажете какое-либо имя столбца в предложении GROUP BY или в статистической функции, оно не будет известно движку SQL, какое значение оно должно вернуть для столбца такого типа.

5 голосов
/ 21 июня 2011

GROUP BY (Transact-SQL) группирует выбранный набор строк в набор строк сводки по значениям одного или нескольких столбцов или выражений в SQL Server 2008 R2.Одна строка возвращается для каждой группы.Агрегатные функции в списке предложений SELECT предоставляют информацию о каждой группе, а не об отдельных строках.

SELECT a.City, COUNT(bea.AddressID) AS EmployeeCount
FROM Person.BusinessEntityAddress AS bea 
    INNER JOIN Person.Address AS a
        ON bea.AddressID = a.AddressID
GROUP BY a.City

Предложение GROUP BY имеет синтаксис, совместимый с ISO, и синтаксис, не совместимый с ISO.В одном операторе SELECT может использоваться только один стиль синтаксиса.Используйте ISO-совместимый синтаксис для всех новых работ.Синтаксис, не совместимый с ISO, предусмотрен для обратной совместимости.

В ISO-совместим синтаксис каждой таблицы или столбца представления в любом неагрегированном выражении в списке должен быть включен в список GROUP BY.

select pub_id, type, avg(price), sum(total_sales)
from titles
group by pub_id, type

Ссылка на Организация результатов запроса по группам: предложение group by

SybaseСинтаксис или не совместимый с ISO снимает ограничения на то, что вы можете включить или пропустить в списке select запроса, который включает group by:

  • Столбцы в списке выбора не ограничиваются группирующими столбцами и столбцами, используемыми с векторными агрегатами.

  • Столбцы, указанные группой, не ограничены этими неагрегированными столбцами.в списке выбора.

Пример:

select type, title_id, avg(price), avg(advance) 
from titles 
group by type 
2 голосов
/ 21 июня 2011

Чтобы использовать агрегатные функции, такие как сумма без группировки по, используйте предложение over.

См: http://msdn.microsoft.com/en-us/library/ms189461.aspx

Пример:

CREATE TABLE #a (ida int, name varchar(50))
CREATE TABLE #b  (ida int, number int)

INSERT INTO #a VALUES(1,'one')
INSERT INTO #a VALUES(2,'two')

INSERT INTO #b VALUES(1,2)
INSERT INTO #b VALUES(1,3)
INSERT INTO #b VALUES(2,1)

SELECT DISTINCT a.ida, sum(number) OVER (PARTITION BY a.ida) FROM #a a
INNER JOIN #b b on a.ida = b.ida
...