【问题标题】:SQL query won't run when using Group By使用 Group By 时 SQL 查询不会运行
【发布时间】:2014-06-10 09:52:39
【问题描述】:

我正在尝试编写一个 SQL 查询来显示发送给客户的最新发票的日期。阅读后,使用 MAX() 聚合函数和 GROUP BY 似乎是要走的路。

但是,我的查询抛出了一个错误。我试过只按函数分组(如下面的代码所示),并按所有内容分组,但都不起作用。

SQL 是:

SELECT
    ClientSupplier.ClientID AS ClientID,
    ClientSupplier.ContactID AS ContactID,
    ClientSupplier.ClientCode AS ClientCode,
    Contact.Pref AS Pref,
    Contact.FName AS FName,
    Contact.LName AS LName,
    ContactPartnerHistory.PartnerID AS PartnerID,
    ContactPartnerHistory.EndDate AS EndDate,
    Partner.PartnerID AS PartnerID2,
    Partner.EmployeeID AS EmployeeID,
    Employee.EmployeeID AS EmployeeID2,
    Employee.PrefTemp AS PrefTemp,
    Employee.FNameTemp AS FNameTemp,
    Employee.SNameTemp AS SNameTemp,
    Bill.BillToClientID AS BillToClientID,
    Bill.InvoiceDate AS InvoiceDate,
    Max(Bill.InvoiceDate) AS MostRecentInvoiceDate
FROM
    Bill 
INNER JOIN 
    (ClientSupplier 
INNER JOIN 
    (Contact 
INNER JOIN 
    (ContactPartnerHistory 
INNER JOIN 
    (Partner 
INNER JOIN 
    Employee ON Partner.EmployeeID = Employee.EmployeeID) 
  ON Partner.PartnerID = ContactPartnerHistory.PartnerID) 
  ON Contact.ContactID = ContactPartnerHistory.ContactId) 
  ON Contact.ContactID = ClientSupplier.ContactID) 
  ON ClientSupplier.ClientID = Bill.BillToClientID
WHERE
   ClientSupplier.ClientCode NOT LIKE '%zz%' 
   AND ContactPartnerHistory.EndDate IS NULL 
   AND Employee.SNameTemp LIKE '%payroll%'
GROUP BY
   Max(Bill.InvoiceDate)

我在这里 checked the answers 重新评估了我收到的错误消息,但他们似乎建议将所有内容包含在组中会清除它,但事实并非如此。

如果我完全排除该函数(并显示所有发票日期),查询就会运行,但这不是我想要的。显然我做错了什么,但是什么?

【问题讨论】:

    标签: sql group-by max aggregate-functions


    【解决方案1】:

    从您的查询来看,您误解了 group by 的实际作用。您有一些列中可能出现重复值。并且您有一个或多个列要在其上应用聚合函数来获取总和或最大值或其他任何内容。 group by 折叠您在 group by 中指定的那些列,并将聚合函数应用于每个组中的行。

    因此,您不应该做的是将聚合函数应用于您分组的列,尤其是在 group by 子句中。

    SELECT
    ClientSupplier.ClientID AS ClientID,
    ClientSupplier.ContactID AS ContactID,
    ClientSupplier.ClientCode AS ClientCode,
    Contact.Pref AS Pref,
    Contact.FName AS FName,
    Contact.LName AS LName,
    ContactPartnerHistory.PartnerID AS PartnerID,
    ContactPartnerHistory.EndDate AS EndDate,
    Partner.PartnerID AS PartnerID2,
    Partner.EmployeeID AS EmployeeID,
    Employee.EmployeeID AS EmployeeID2,
    Employee.PrefTemp AS PrefTemp,
    Employee.FNameTemp AS FNameTemp,
    Employee.SNameTemp AS SNameTemp,
    Bill.BillToClientID AS BillToClientID,
    Bill.InvoiceDate AS InvoiceDate,
    Max(Bill.InvoiceDate) AS MostRecentInvoiceDate
    FROM
        Bill INNER JOIN (ClientSupplier INNER JOIN (Contact INNER JOIN (ContactPartnerHistory INNER JOIN (Partner INNER JOIN Employee ON Partner.EmployeeID = Employee.EmployeeID) ON Partner.PartnerID = ContactPartnerHistory.PartnerID) ON Contact.ContactID = ContactPartnerHistory.ContactId) ON Contact.ContactID = ClientSupplier.ContactID) ON ClientSupplier.ClientID = Bill.BillToClientID
    WHERE
        ClientSupplier.ClientCode NOT LIKE '%zz%' AND ContactPartnerHistory.EndDate IS NULL AND Employee.SNameTemp LIKE '%payroll%'
    GROUP BY
    ClientSupplier.ClientID AS ClientID,
    ClientSupplier.ContactID AS ContactID,
    ClientSupplier.ClientCode AS ClientCode,
    Contact.Pref AS Pref,
    Contact.FName AS FName,
    Contact.LName AS LName,
    ContactPartnerHistory.PartnerID AS PartnerID,
    ContactPartnerHistory.EndDate AS EndDate,
    Partner.PartnerID AS PartnerID2,
    Partner.EmployeeID AS EmployeeID,
    Employee.EmployeeID AS EmployeeID2,
    Employee.PrefTemp AS PrefTemp,
    Employee.FNameTemp AS FNameTemp,
    Employee.SNameTemp AS SNameTemp,
    Bill.BillToClientID AS BillToClientID,
    Bill.InvoiceDate AS InvoiceDate
    

    您应该包含您在selecting 但没有应用聚合函数的所有列。这就是错误所说的。

    MySQL 允许不遵循上述规则(如果您的管理员没有通过设置 sql-mode 来禁止),但请记住,然后会显示每个组的随机行。

    如果您不想group by 所有这些列,this very usefull manual entry(也适用于其他 RDBMS)解释了如何获取与每个组的最大值对应的行。

    【讨论】:

    • 谢谢 - 是的,我正在看它。
    • 我还排除了发票日期,因为那会破坏集团,只是使用该功能。
    【解决方案2】:
    SELECT
    ClientSupplier.ClientID AS ClientID,
    ClientSupplier.ContactID AS ContactID,
    ClientSupplier.ClientCode AS ClientCode,
    Contact.Pref AS Pref,
    Contact.FName AS FName,
    Contact.LName AS LName,
    ContactPartnerHistory.PartnerID AS PartnerID,
    ContactPartnerHistory.EndDate AS EndDate,
    Partner.PartnerID AS PartnerID2,
    Partner.EmployeeID AS EmployeeID,
    Employee.EmployeeID AS EmployeeID2,
    Employee.PrefTemp AS PrefTemp,
    Employee.FNameTemp AS FNameTemp,
    Employee.SNameTemp AS SNameTemp,
    Bill.BillToClientID AS BillToClientID,
    Bill.InvoiceDate AS InvoiceDate,
    Max(Bill.InvoiceDate) AS MostRecentInvoiceDate
    FROM
    Bill INNER JOIN (ClientSupplier INNER JOIN (Contact INNER JOIN (ContactPartnerHistory INNER JOIN (Partner INNER JOIN Employee ON Partner.EmployeeID = Employee.EmployeeID) ON Partner.PartnerID = ContactPartnerHistory.PartnerID) ON Contact.ContactID = ContactPartnerHistory.ContactId) ON Contact.ContactID = ClientSupplier.ContactID) ON ClientSupplier.ClientID = Bill.BillToClientID
    WHERE
    ClientSupplier.ClientCode NOT LIKE '%zz%' AND ContactPartnerHistory.EndDate IS NULL 
    AND Employee.SNameTemp LIKE '%payroll%'
    GROUP BY
    ClientSupplier.ClientID AS ClientID,
    ClientSupplier.ContactID AS ContactID,
    ClientSupplier.ClientCode AS ClientCode,
    Contact.Pref AS Pref,
    Contact.FName AS FName,
    Contact.LName AS LName,
    ContactPartnerHistory.PartnerID AS PartnerID,
    ContactPartnerHistory.EndDate AS EndDate,
    Partner.PartnerID AS PartnerID2,
    Partner.EmployeeID AS EmployeeID,
    Employee.EmployeeID AS EmployeeID2,
    Employee.PrefTemp AS PrefTemp,
    Employee.FNameTemp AS FNameTemp,
    Employee.SNameTemp AS SNameTemp,
    Bill.BillToClientID AS BillToClientID,
    Bill.InvoiceDate AS InvoiceDate
    

    请始终牢记一件事,即当您将聚合函数与其他列一起使用时,请使用 group by 子句绑定所有其他列。

    【讨论】:

    • 您提供了错误的答案。然后,当我的答案被接受时,您复制我的答案。为了什么?这个网站不是我们为了声誉点而玩的游戏。这些要点旨在通过鼓励人们删除错误/多余的答案来帮助保持网站清洁。顺便说一句,如果您这样做,您将恢复失去的声誉。
    猜你喜欢
    • 1970-01-01
    • 2014-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-03
    • 2021-10-26
    • 2021-11-17
    相关资源
    最近更新 更多