2017-02-22 20 views
1

我碰到了一个障碍,似乎无法弄清楚这一点。我怀疑这个答案正在盯着我,但似乎无法把我的大脑包围起来,而且我也找不到在线解决方案。按人物排前十位,按人排列

我试图找出每个员工在给定范围内每天完成的最后一个订单。问题是订单号码不是顺序的,所以我不能只用MAX()函数来查找它。最后,我不需要任何东西,除了 OrderNums的列表(每个员工每天的最后一个),因为这将被添加到另一个查询中。

这是我到目前为止有:

SELECT  
    (SELECT USERNAME FROM EMPLOYEES WHERE TechID = Invoices.TechID1) AS "Tech" 
      ,CONVERT(date, OrderDate) AS "OrderDate" 
     FROM Invoices 
       WHERE OrderDate BETWEEN CONVERT(date, DATEADD(day, -60, GETDATE())) AND CONVERT(date, GETDATE()) 
     GROUP BY 
      TechID1, OrderDate 

     ORDER BY  
      "Tech" DESC, OrderDate DESC 

这将返回每个员工每一天,这是伟大的一个线,但我无法弄清楚如何指定每一天的最后一个订单号。这样做的最好的领域是超时(时间发票结束了),所以我一直在试图SELECT子句中添加一行像

(SELECT TOP 1 OrderNum FROM Invoices ii Where ii.TechID1 = Invoices.TechID1 AND ii.OrderDate = Invoices.OrderDate ORDER BY TimeOut DESC) 

但这并不一致好像有应该是一个更简单的方法来做到这一点。看起来你应该能够将OrderNum添加到SELECT子句中,但会引发错误(42000 - [SQL Server]列'Invoices.OrderNum'在选择列表中无效,因为它不包含在聚合函数中或GROUP BY子句。)

有什么建议吗?

P.S.你们真棒。我得到很多通过淘洗此网站回答的问题。我还不能在这里回复,因为我太绿了,所以我现在要说谢谢!

- 编辑 -

戈登Linhoff - 感谢您的建议。这很有帮助,但是它只能为每个人返回几个结果,并且我们预计在60天期间会有近40个结果。我会做一些挖掘这个操作,因为我不知道这是一件事情。我对SQL依然很陌生。

McNetsydoow - 我不知道你想什么所有的细节,但希望这是有帮助的:

发票表

  • LocationID
  • InvoiceNum
  • WorkDate
  • TimeOut
  • TechID1
  • (这里不太可能有帮助的其他列的加载。)

EmployeesTable

  • 用户名
  • TechID
  • (即不太可能有帮助这里等栏目的负载。)

此外,如果您有所帮助。目前的查询看起来像这样:

SELECT 
    ... 
FROM Invoices WHERE 
    OrderNum IN (
     SELECT "Last OrderNum" FROM 
     (SELECT 
      (SELECT TOP 1 OrderNum FROM PestPac.dbo.INVOICES WHERE (TechID1 = Employees.TechID OR TechID2 = Employees.TechID) 
        AND NOT (OrderNum IS NULL) 
        AND NOT (InvoiceType = 'NS') --Not Serviced 
        AND VOID = 0 --Not Voided 
        AND CONVERT(date,WorkDate)= CONVERT(date, DATEADD(day, -7, GETDATE())) 
        AND NOT (OrderType = 'NS') ORDER BY WorkDate DESC) AS "Last OrderNum" 
        FROM Employees 
        WHERE 
         AND Employees.active = 1 
     ) todayMinusSeven) 
OR 
    OrderNum IN (...) todayMinusSix) 
OR 
    OrderNum IN (...) todayMinusFive) 
OR 
    OrderNum IN (...) todayMinusFour) 
OR 
    OrderNum IN (...) todayMinusThree) 
OR 
    OrderNum IN (...) todayMinusTwo) 
OR 
    OrderNum IN (...) todayMinusOne) 

基本上,我对员工表使用子查询来获取每个人在给定日期完成的最后一个订单号,然后在目标日更改的情况下重复相同的查询。这给了我7个订单号列表,我转过身来用它来过滤发票表,然后从那里获取我想要的数据。这是一个文明时代的不起眼的武器。如上所述,此更改的目标是使用一个包含工件的BETWEEN X和Y子句的子查询。

+0

请添加员工和发票的最小表格模式。 – McNets

+0

看起来像一个问题可以通过常见的表格来解决?如果您可以提供样本数据和预期输出,会更容易。 – ydoow

回答

1

嗯。我认为你可以使用row_number()

SELECT i.* 
FROM (SELECT i.*, 
      ROW_NUMBER() OVER (PARTITION BY TechId1, CONVERT(date, OrderDate) ORDER BY OrderDate DESC) as seqnum 
     FROM Invoices i 
     WHERE OrderDate BETWEEN CONVERT(date, DATEADD(day, -60, GETDATE())) AND CONVERT(date, GETDATE()) 
    ) i 
WHERE seqnum = 1; 

这将选择整个行。您可以选择所需的特定列。