SQL - 查找字段中的最新日期和附加到这些记录的数据

时间:2014-10-03 15:14:30

标签: sql oracle

我试图找到以下信息 - 如果货物上有数百个案例,我只想要创建的最后一个案例以及随附的货件详细信息。似乎设置MAX(CH.CREATE_DATE_TIME)或MIN(CH.CREATE_DATE_TIME)都返回要创建的FIRST(最旧)个案而不是最后一个(最近的)。

此查询将返回上周所有货件及其最近创建的案例。

SELECT AH.TRLR_NBR, AH.SHPMT_NBR, AH.SHPD_DATE, AH.ARRIVAL_DATE_TIME, 
MAX(CH.CREATE_DATE_TIME), CH.CASE_NBR FROM ASN_HDR AH
INNER JOIN CASE_HDR CH
ON CH.RCVD_SHPMT_NBR = AH.SHPMT_NBR
WHERE CH.CREATE_DATE_TIME > SYSDATE-7
GROUP BY AH.TRLR_NBR, AH.SHPMT_NBR, AH.SHPD_DATE, AH.ARRIVAL_DATE_TIME, CH.CASE_NBR
ORDER BY AH.ARRIVAL_DATE_TIME

3 个答案:

答案 0 :(得分:0)

您可以尝试订购聚合:

SELECT AH.TRLR_NBR
     , AH.SHPMT_NBR
     , AH.SHPD_DATE
     , AH.ARRIVAL_DATE_TIME
     , MAX(CH.CREATE_DATE_TIME) KEEP
         (DENSE_RANK LAST
          ORDER BY CH.CREATE_DATE_TIME) CREATE_DATE_TIME
     , MAX(CH.CASE_NBR) KEEP
         (DENSE_RANK LAST
          ORDER BY CH.CREATE_DATE_TIME) CASE_NBR
FROM ASN_HDR AH
     INNER JOIN CASE_HDR CH
       ON CH.RCVD_SHPMT_NBR = AH.SHPMT_NBR
WHERE AH.SHPD_DATE > SYSDATE-7
GROUP BY AH.TRLR_NBR
       , AH.SHPMT_NBR
       , AH.SHPD_DATE
       , AH.ARRIVAL_DATE_TIME
ORDER BY AH.ARRIVAL_DATE_TIME

答案 1 :(得分:0)

分析ROW_NUMBER函数是一个很好的工具,可以根据行中的最大/最小值来获取整行。

此查询将对每个货件的创建日期进行排名。排名基于CREATE_DATE_TIME降序排列,因此最新排名将首先出现:

SELECT
  AH.TRLR_NBR,
  AH.SHPMT_NBR,
  AH.SHPD_DATE,
  AH.ARRIVAL_DATE_TIME,
  CH.CASE_NBR,
  ROW_NUMBER() OVER (
    PARTITION BY AH.SHPMT_NBR
    ORDER BY CH.CREATE_DATE_TIME DESC) AS CreateRank
FROM ASN_HDR AH
INNER JOIN CASE_HDR CH ON CH.RCVD_SHPMT_NBR = AH.SHPMT_NBR
WHERE CH.CREATE_DATE_TIME > SYSDATE-7

现在您已经对它们进行了排名,您可以将最终结果限制为具有CreateRank = 1的行。遗憾的是,您不能直接执行此操作,因为分析函数在应用任何WHEREHAVING条件后运行。相反,您需要将其推入子查询:

SELECT * FROM (
  SELECT
    AH.TRLR_NBR,
    AH.SHPMT_NBR,
    AH.SHPD_DATE,
    AH.ARRIVAL_DATE_TIME,
    CH.CASE_NBR,
    ROW_NUMBER() OVER (
      PARTITION BY AH.SHPMT_NBR
      ORDER BY CH.CREATE_DATE_TIME DESC) AS CreateRank
  FROM ASN_HDR AH
  INNER JOIN CASE_HDR CH ON CH.RCVD_SHPMT_NBR = AH.SHPMT_NBR
  WHERE CH.CREATE_DATE_TIME > SYSDATE-7
) WHERE CreateRank = 1;

答案 2 :(得分:0)

另一种解决方案是使用CTE预先审核max(CREATE_DATE_TIME),然后通过连接过滤主要查询结果到CTE。这意味着在查询运行之前需要做更多的工作,但只要您有适当的支持索引,主要查询执行时的工作就会减少。有点像:

;WITH YourCTE AS
(
SELECT AH.SHPMT_NBR, max(CH.CREATE_DATE_TIME) AS [CREATE_DATE_TIME]
FROM ASN_HDR AH
INNER JOIN CASE_HDR CH
ON CH.RCVD_SHPMT_NBR = AH.SHPMT_NBR
WHERE CH.CREATE_DATE_TIME > SYSDATE-7
GROUP BY AH.SHPMT_NBR 
)

SELECT AH.TRLR_NBR
, AH.SHPMT_NBR
, AH.SHPD_DATE
, AH.ARRIVAL_DATE_TIME
, cte.CREATE_DATE_TIME
, CH.CASE_NBR 
FROM ASN_HDR AH
INNER JOIN CASE_HDR CH
ON CH.RCVD_SHPMT_NBR = AH.SHPMT_NBR
INNER JOIN YourCTE cte 
ON AH.SHPMT_NBR = cte.SHPMT_NBR AND CH.CH.CREATE_DATE_TIME = cte.CREATE_DATE_TIME
ORDER BY AH.ARRIVAL_DATE_TIME