我的查询 -
select cu.CustomerID,cu.FirstName,cu.LastName, COUNT(si.InvoiceID)as inv --1
from Customer as cu inner join SalesInvoice as si --2
on cu.CustomerID = si.CustomerID -- 3
-- put the WHERE clause here ! --4
group by cu.CustomerID,cu.FirstName,cu.LastName -- 5
where cu.FirstName = 'mark' -- 6
输出正确的代码 -
我得到错误 - 关键字'where'附近的语法不正确。
你能告诉我为什么会收到这个错误吗? 我想知道为什么WHERE出现在GROUP BY之前而不是之后。
答案 0 :(得分:18)
您的订单有误。 WHERE
子句位于GROUP BY
:
select cu.CustomerID,cu.FirstName,cu.LastName, COUNT(si.InvoiceID)as inv
from Customer as cu
inner join SalesInvoice as si
on cu.CustomerID = si.CustomerID
where cu.FirstName = 'mark'
group by cu.CustomerID,cu.FirstName,cu.LastName
如果您想在GROUP BY
之后执行过滤器,那么您将使用HAVING
子句:
select cu.CustomerID,cu.FirstName,cu.LastName, COUNT(si.InvoiceID)as inv
from Customer as cu
inner join SalesInvoice as si
on cu.CustomerID = si.CustomerID
group by cu.CustomerID,cu.FirstName,cu.LastName
having cu.FirstName = 'mark'
HAVING
子句通常用于聚合函数过滤,因此在GROUP BY
要了解此处的操作顺序,请article explaining the order。从文章中,SQL中的操作顺序是:
首先,我认为查找执行SQL指令的顺序会很好,因为这将改变我可以优化的方式:
FROM clause
WHERE clause
GROUP BY clause
HAVING clause
SELECT clause
ORDER BY clause
使用此订单,您将在WHERE
之前的GROUP BY
中应用过滤器。 WHERE
用于限制记录数。
以这种方式思考,如果您之后应用WHERE
,那么您将返回更多记录,然后您想要分组。首先应用它,减少记录集然后应用分组。
答案 1 :(得分:3)
where
子句位于group by
之前,因为从概念上讲,您在分组之前进行过滤,而不是之后。您希望将分组的输出限制为仅匹配的输出,而不是对由于过滤器而可能会丢弃的项目执行分组。
答案 2 :(得分:2)
SQL允许您过滤GROUP BY的结果 - 它被称为HAVING子句。
如果你想过滤在分组之前可以确定的东西(即每个人都有FirstName ='Mark'),那就是通过WHERE完成的。
但是,如果你想过滤每个有4张或更多发票的人(比如在做COUNT之后你就不会知道的话),那么你就可以使用HAVING了。
答案 3 :(得分:2)
在WHERE
之前使用GROUP BY
子句,因为它更有意义。在分组之前使用WHERE
子句中指定的过滤器。分组后,您可以使用HAVING
子句,类似于WHERE
,但您也可以按聚合值进行过滤。
比较
-- Select the number of invoices per customer (for Customer 1 only)
SELECT
si.CustomerID,
COUNT(*) as InvoiceCount
FROM
SalesInvoice as si
WHERE
si.CustomerID = 1
-- You cannot filter by count(*) here, because grouping hasn't taken place yet.
GROUP BY
si.CustomerID -- (Not needed in this case, because of only 1 customer)
针对
-- Select all invoices of customers that have more than three invoices
SELECT
si.CustomerID,
COUNT(*) as InvoiceCount
FROM
SalesInvoice as si
GROUP BY
si.CustomerId
HAVING
-- You can filter by aggregates, like count, here.
COUNT(*) > 3
答案 4 :(得分:1)
假设您的数据库中有100,000人。其中9人被命名为马克。为什么数据库应该对所有100,000进行Count操作,然后抛出99,991 NOT not named Mark?首先过滤掉Marks似乎更聪明,然后只计数9次?使操作更快。