使用Group By时不会运行SQL查询

时间:2014-06-10 09:52:39

标签: sql group-by max aggregate-functions

我尝试编写一个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在这里重新调整了我收到的错误消息,但他们似乎建议将群组中的所有内容都清除,但事实并非如此。

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

2 个答案:

答案 0 :(得分: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

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

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

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

答案 1 :(得分:-1)

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子句绑定所有其他列。