让所有行至少在特定的次数出现在另一个表中

时间:2013-09-04 06:59:31

标签: sql join group-by having

我正在使用示例database,我希望在表CustomersOrders上编写一个查询,该查询为所有已完成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语句中的所需列中。有什么问题,为了工作,我怎么能修改第二个查询,即使它可能是多余的陈述?

3 个答案:

答案 0 :(得分:0)

来自SQL GROUP BY Statement

  

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;

因此,对于使用聚合,您需要指定要聚合的列,并且为此您不能使用*

您必须明确指定SELECTGROUP 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