我正在使用示例database,我希望在表Customers
和Orders
上编写一个查询,该查询为所有已完成2个以上订单的客户提供服务。虽然我通过查询得出了这个:
Select Customers.*
From Customers
Where Customers.CustomerID IN(
Select Orders.CustomerID
From Orders
Group by Orders.CustomerID
Having count(*)>2
);
我无法理解为什么查询:
SELECT Customers.*
FROM Orders
INNER JOIN Customers
ON Orders.CustomerID=Customers.CustomerID
GROUP BY Customers.CustomerID
HAVING COUNT(*)>2;
无法给出相同的结果。来自数据库的消息是:
“无法对使用'*'(客户)选择的字段进行分组。”
我的印象是它应该有效,因为Customers.CustomerID
包含在Select
语句中的所需列中。有什么问题,为了工作,我怎么能修改第二个查询,即使它可能是多余的陈述?
答案 0 :(得分:0)
GROUP BY语句与聚合一起使用 函数用于将结果集分组为一列或多列。
SQL GROUP BY Syntax
SELECT column_name, aggregate_function(column_name)
FROM table_name
WHERE column_name operator value
GROUP BY column_name;
因此,对于使用聚合,您需要指定要聚合的列,并且为此您不能使用*
您必须明确指定SELECT
和GROUP BY
子句中的列。
答案 1 :(得分:0)
在SELECT
声明中指定所需的列:
SELECT Customers.CustomerID, Customers.CustomerName
FROM Orders
INNER JOIN Customers
ON Orders.CustomerID=Customers.CustomerID
GROUP BY Customers.CustomerID, Customers.CustomerName
HAVING COUNT(*)>2;
答案 2 :(得分:0)
您的第一个解决方案实际上是由两个查询构成的
第二部分用于通过列出CustomerID
来确定回头客 Select o.CustomerID
From Sales.SalesOrderHeader o
Group by o.CustomerID
Having count(*)>2
第一部分通过使用第二个查询获得的返回客户列表显示客户详细信息
Select c.*
From Sales.Customer c
Where
c.CustomerID IN(
...
);
在尝试使用订购表上的分组依据语法获取同意客户ID时,无法返回所有客户数据
但是,可以在此处使用带有PARTITION BY子句的SQL聚合函数(下面的Count函数)而不是Group By 请查看教程http://www.kodyaz.com/t-sql/sql-count-function-with-partition-by-clause.aspx并查看以下查询
select * from (
SELECT distinct
c.*,
COUNT(o.SalesOrderID) over (partition by c.CustomerId) cnt
FROM Sales.SalesOrderHeader o
INNER JOIN Sales.Customer c ON o.CustomerID = c.CustomerID
) t where cnt > 1