【问题标题】:Give all rows appear in another table at least specific number of times让所有行至少出现在另一个表中的特定次数
【发布时间】:2013-09-04 06:59:30
【问题描述】:

我正在使用示例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 语句的要求列中。有什么问题,我如何修改第二个查询才能工作,即使它执行了可能是多余的语句?

【问题讨论】:

    标签: sql join group-by having


    【解决方案1】:

    来自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 子句中明确指定列。

    【讨论】:

    • 我已经尝试了你的建议,它有效,但它只给出了 ID。为了获得完整的信息,我需要把它放在一个子查询中,并在外部查询中使用 IN 或 EXISTS 检查它的匹配度。
    【解决方案2】:

    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;
    

    【讨论】:

    • 它适用于这些特定的表,但我想知道如果两个客户具有相同的名称是否会出现问题。可能不是,因为两者都是分组的。我说的对吗?
    • 你说得对,但在这种情况下,你应该从 SELECTGROUP BY 中删除 Customers.CustomerID
    【解决方案3】:

    您的第一个解决方案实际上由两个查询组成

    第二部分用于通过列出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(
        ...
    );
    

    在尝试使用 Order 表上的 Group By 语法获取重复的客户 ID 时,无法返回所有客户数据

    但是这里可以使用带有 PARTITION BY 子句的 SQL 聚合函数(下面的计数函数)而不是 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-24
      • 2020-05-28
      • 1970-01-01
      • 2018-12-08
      • 1970-01-01
      相关资源
      最近更新 更多