我遇到了障碍,似乎无法解决这个问题。我怀疑答案是盯着我看,但似乎无法将我的大脑包裹起来,我无法在线找到解决方案。
我试图找到每个员工在给定范围内每天完成的最后一个订单。问题是订单号不是顺序的,所以我不能只使用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
每天为每位员工返回一行,这很好,但我无法弄清楚如何指定每天的最后一个订单号。最好的字段是TimeOut(发票完成的时间),所以我一直试图在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] Column' Invoices.OrderNum'在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句。)
有什么建议吗?
P.S。你们真棒。我通过搜索这个网站得到了很多的问题。我现在还不能回复,因为我太绿了,所以我现在就说谢谢了!
- 编辑 -
Gordon Linhoff - 感谢您的建议。这很有帮助,但它只能为每个人返回几个结果,并且我们期望在60天内更接近40。我会对这个操作进行一些挖掘,因为我不知道这是一件事。我还不熟悉SQL。
McNets 和 ydoow - 我不确定您想要的所有详细信息,但希望这会有所帮助:
发票表
EmployeesTable
如果这有帮助,当前查询看起来像这样:
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)
基本上,我使用针对employees表的子查询来获取每个人在给定日期完成的最后一个订单号,然后在仅更改目标日的情况下重复相同的查询。这给了我7个订单号列表,我转过来用来过滤Invoice表,然后从那里得到我想要的数据。对于文明时代来说,它是非常不优雅的武器。如上所述,此更改的目标是使用 Workdate BETWEEN X和Y 子句创建一个子查询。
答案 0 :(得分: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;
这将选择整行。您可以选择所需的特定列。