多对多查询中的最近日期

时间:2017-04-28 13:12:54

标签: sql sql-server

我正在尝试查询未在我的系统中移动超过90天的部件。我开始遇到一个多对多的问题,我对SQL很新。

它需要像:

  • 查找OrderStatus ='Open'
  • 的所有PartNos
  • 然后查看PO DateEnt,确定它是否> 90天
  • 然后查看TimeTicket,确定它是否> 90天

符合所有条件,在查询中发布结果。

DECLARE @now DATETIME
DECLARE @90daysago DATETIME


SET @now = GETDATE()
SET @90daysago = DATEADD(day, -90, @now)



SELECT
    o.PartNo,
    o.JobNo,
    o.Status,

    cast(po.DateEnt as DATE) AS DateEnt,


    tt.TicketDate,
    (o.qtyToMake - o.QtyShipped2Stock) AS NumOpen

FROM
    OrderDet AS o

INNER JOIN PODet AS pod
    ON o.PartNo = pod.PartNo

INNER JOIN PO as po
    ON pod.PONum = po.PONum

INNER JOIN TimeTicketDet as tt
    ON o.JobNo = tt.JobNo

WHERE
    o.Status = 'Open' AND
    o.PartNo = '72347' AND
    o.JobNo = '16516-02'


ORDER BY
    po.DateEnt DESC

https://photos.google.com/share/AF1QipMPAogamiVv_19JAQHO3GBYsBr9s6PPt-WXGbdrPTqvW-EAU0QjkCI0s-cidT-IuQ?key=ZElDNzFsdmU2XzZPVmh1d01tWWZLcU1WbllDUzN3

上面的链接显示了一段已执行的查询,我在模拟PartNo上运行它。

第一列分别是PartNo,JobNo。

这两个日期分别是DateEnt,TicketDate。

如您所见,我们系统中的每一次更改都会复制数据并显示所有日期。当我添加标准> @ 90daysago时,它将显示一个2016年12月19日的DateEnt,这是一个已关闭的订单。我知道这是非常模糊的,我只是不知道如何只显示查询的每个日期的最新值。我很乐意提供更多有用的信息。

Sample Data
+--------+-------+--------+------------+------------+
| PartNo | JobNo | Status |  DateEnt   | TicketDate |
+--------+-------+--------+------------+------------+
|  72347 |     1 | OPEN   | 12/19/2016 | 10/6/2016  |
|  72347 |     2 | OPEN   | 12/19/2016 | 10/5/2016  |
|  72347 |     3 | OPEN   | 12/19/2016 | 12/23/2016 |
|  72347 |     4 | OPEN   | 12/19/2016 | 12/23/2016 |
|  72347 |     1 | OPEN   | 12/19/2016 | 10/6/2016  |
|  72347 |     2 | OPEN   | 3/30/2017  | 10/5/2016  |
|  72347 |     3 | OPEN   | 3/30/2017  | 12/23/2016 |
|  72347 |     4 | OPEN   | 3/30/2017  | 12/23/2016 |
|  72347 |     1 | OPEN   | 3/30/2017  | 10/6/2016  |
|  72347 |   200 | OPEN   | 1/9/2017   | 10/5/2016  |
|  72347 |     3 | OPEN   | 3/30/2017  | 12/23/2016 |
|  72347 |     4 | OPEN   | 3/30/2017  | 12/26/2016 |
|  72347 |     1 | OPEN   | 3/30/2017  | 10/6/2016  |
|  72347 |     2 | OPEN   | 3/30/2017  | 10/5/2016  |
|  72347 |     3 | OPEN   | 3/30/2017  | 12/23/2016 |
|  72347 |     4 | OPEN   | 3/30/2017  | 12/23/2016 |
+--------+-------+--------+------------+------------+

Sample Result
+--------+-------+--------+----------+------------+--+
| PartNo | JobNo | Status | DateEnt  | TicketDate |  |
+--------+-------+--------+----------+------------+--+
|  72347 |   200 | OPEN   | 1/9/2017 | 10/5/2017  |  |
+--------+-------+--------+----------+------------+--+

1 个答案:

答案 0 :(得分:1)

请试试这个。您可以调整PARTITION BY和ORDER BY以满足您的要求。

;WITH cte AS(SELECT o.PartNo
   , o.JobNo
   , o.Status
   , CAST(po.DateEnt as DATE) AS DateEnt
   , tt.TicketDate
   , (o.qtyToMake - o.QtyShipped2Stock) AS NumOpen
   , ROW_NUMBER() OVER(PARTITION BY o.PartNo ORDER BY po.DateEnt DESC, tt.TicketDate DESC) AS Rownum
FROM OrderDet AS o
INNER JOIN PODet AS pod
    ON o.PartNo = pod.PartNo
INNER JOIN PO AS po
    ON pod.PONum = po.PONum
INNER JOIN TimeTicketDet AS tt
    ON o.JobNo = tt.JobNo
WHERE o.Status = 'Open' 
AND po.DateEnt < CONVERT(VARCHAR(10), DATEADD(DAY, -90, GETDATE()), 120)
)

SELECT *
FROM cte
WHERE Rownum = 1
AND TicketDate < CONVERT(VARCHAR(10), DATEADD(DAY, -90, GETDATE()), 120);