Kal*_*sin 3 sql-server aggregate-functions
假设我有一张公司表:
Company
coID | coName | coCSR
Run Code Online (Sandbox Code Playgroud)
该coCSR字段是与帐户处理程序表相关的数字ID:
AccountHandler
ahID | ahFirstName | ahLastName
Run Code Online (Sandbox Code Playgroud)
我还有一张订单表:
Order
orID | orCompanyID | orDate | orValue
Run Code Online (Sandbox Code Playgroud)
现在我需要生成的输出结构如下:
Company | Account handler | No. of orders | Total of orders
Run Code Online (Sandbox Code Playgroud)
这是我试过的查询,它产生一个错误:
SELECT coID, coName, ahFirstName+' '+ahLastName AS CSRName, COUNT(orID) AS numOrders, SUM(orValue) AS totalRevenue
FROM Company
LEFT JOIN AccountHandler ON coCSR = ahID
LEFT JOIN Order ON coID = orCompanyID
WHERE coCSR = 8
AND orDate > getdate() - 365
ORDER BY coName ASC
Run Code Online (Sandbox Code Playgroud)
错误是:列名'AccountHandler.ahLastName'在ORDER BY子句中无效,因为它不包含在聚合函数中,并且没有GROUP BY子句.
如果我使用GROUP BY coID,我会在关键字'WHERE'附近获得不正确的语法.如果由于聚合函数而更改了WHEREto HAVING,我会收到错误,告诉我删除聚合函数或GROUP BY子句中未包含的每个其他列名.
我不得不承认,除了最基本的SQL命令之外,我还没有理解任何逻辑和语法,我只是试图应用我以前见过的东西,而且它不起作用.请帮我搞定这个.更好的是,你能帮助我理解为什么它现在不起作用吗?:)
首先,您的查询可能已丢失FROM Company,但在撰写帖子时可能会以某种方式丢失.
您似乎是按公司汇总数据.因此,您需要按公司分组.您尝试分组失败的最可能原因可能是因为您放GROUP BY错了地方.我认为你之前提出过WHERE,但事实上它应该追求它(之前ORDER BY):
SELECT
c.coID,
c.coName,
a.ahFirstName + ' ' + a.ahLastName AS CSRName,
COUNT(o.orID) AS numOrders,
SUM(o.orValue) AS totalRevenue
FROM Company c
LEFT JOIN AccountHandler a ON c.coCSR = a.ahID
LEFT JOIN [Order] o ON c.coID = o.orCompanyID
WHERE c.coCSR = 8
AND o.orDate > getdate() - 365
GROUP BY ...
ORDER BY c.coName ASC
Run Code Online (Sandbox Code Playgroud)
另一个问题是,分组是什么.SQL Server要求指定所有非聚合列GROUP BY.因此,您的GROUP BY子句应如下所示:
GROUP BY
c.coID,
c.coName,
a.ahFirstName,
a.ahLastName
Run Code Online (Sandbox Code Playgroud)
请注意,您不能通过SELECT子句中指定给它们的别名来引用列(例如CSRName).但是您可以使用ahFirstName+' '+ahLastName表达式而不是相应的列,在这种特定情况下它不会有任何区别.
如果你需要更多的非汇总列添加到这个查询,你将不得不他们两个增加SELECT和GROUP BY.在某些时候,这可能会变得有点单调乏味.我建议你尝试以下方法:
SELECT
c.coID,
c.coName,
a.ahFirstName + ' ' + a.ahLastName AS CSRName,
ISNULL(o.numOrders, 0) AS numOrders,
ISNULL(o.totalRevenue, 0) AS totalRevenue
FROM Company c
LEFT JOIN AccountHandler a ON c.coCSR = a.ahID
LEFT JOIN (
SELECT
orCompanyID,
COUNT(orID) AS numOrders,
SUM(orValue) AS totalRevenue
FROM [Order]
GROUP BY
orCompanyID
WHERE orDate > getdate() - 365
) o ON c.coID = o.orCompanyID
WHERE c.coCSR = 8
ORDER BY c.coName ASC
Run Code Online (Sandbox Code Playgroud)
也就是说,聚合Order仅在表格上完成.然后,聚合的行集将连接到其他表.现在,您可以拉更多的属性来输出从任一Company或AccountHandler无需担心将其添加到GROUP BY,因为不需要在该级别的任何更多的分组.