T-SQL仅查询开始日期和结束日期之间的发票

时间:2017-09-07 19:12:17

标签: sql sql-server tsql date ssms

我有一个会计年度的开始日期和结束日期范围:7/1/16 - 6/30/17

我的查询中包含的日期字段是付款日期,可能在6/30/17之外。

示例:

  Company  PayonDate
  Bose      9/30/17 <---Outside the 6/30/17 date range and will not show on report. This date will pay in advance. 

我想在日期范围内显示最后一个付款日期:

示例:

 Company    PayonDate
 Bose       4/1/17 <----Actual paid on date vs. pay on date in the future within the date range. 

有办法做到这一点吗?

提前致谢!

更新:

   SELECT 
   ven.VendorID,
   ven.Name AS [Vendor Name],
   inv.ReferenceNumber AS [Ref. No],
   inv.InvoiceNumber AS [Invoice No],
   inv.Payment AS Payment,
   SubMax.[Pay On Date]
   FROM inv
     INNER JOIN 
        (
        SELECT MAX(ips.PayOnDateTime) AS [Pay On Date], VendorID
        from inv
       LEFT JOIN ips ON ips.SourceID = inv.SourceID AND     ips.InvoiceID     = inv.InvoiceID
        Group by VendorID
       ) SubMax 
       on inv.VendorID = SubMax.VendorID 
    INNER JOIN ven ON inv.SourceID = ven.SourceID AND inv.VendorID = ven.VendorID
   LEFT JOIN ips ON ips.SourceID = inv.SourceID AND ips.InvoiceID = inv.InvoiceID
    WHERE FacilityID = 'HMC'
    AND SubMax.[Pay On Date] BETWEEN @StartDate AND @EndDate
    AND inv.ReferenceNumber LIKE '__-____'
    ORDER BY ven.Name, SubMax.[Pay On Date]

2 个答案:

答案 0 :(得分:0)

我发现日期维度表是一个上帝发送,特别是在处理不在1月1日开始的FY季度时。他们添加了一个额外的表来加入,但是他们节省了大量的处理和思维。对于一个好日期的昏暗表,请参阅Aaron Bertrand的例子 - https://www.mssqltips.com/sqlservertip/4054/creating-a-date-dimension-or-calendar-table-in-sql-server/。根据您的需要进行定制;我已经制作了几个不同的版本,有时以它为基础开始。但请记住,目标是创建一次并在需要时使用它。

在上面的示例中,构建一个日期表,列出大范围日期的所有日期,并包括会计年度。然后,只需在FY为您需要参考的年份的日期加入日期表。

窗口功能也派上用场。它可能是这样的:

SELECT * 
FROM (
    SELECT 
          ven.VendorID
        , ven.Name AS [Vendor Name]
        , inv.ReferenceNumber AS [Ref. No]
        , inv.InvoiceNumber AS [Invoice No]
        , inv.Payment AS Payment
        , ips.PayOnDateTime AS [Pay On Date]
        , d.theFYYear
        , ROW_NUMBER() OVER (PARTITION BY inv.InvoiceNumber ORDER BY ips.payOnDateTime DESC) AS rn
    FROM ven
    INNER JOIN inv ON ven.vendorID = inv.vendorID
        AND inv.FacilityID = 'HMC'
        AND inv.ReferenceNumber LIKE '__-____'
    INNER JOIN ips ON ips.SourceID = inv.SourceID 
        AND ips.InvoiceID = inv.InvoiceID
        AND ips.PayOnDateTime >= @StartDate
        AND ips.PayOnDateTime <= @EndDate
    INNER JOIN ref_DateDimension d ON ips.PayOnDateTime = d.theDate
        AND d.theFYYear = 'FY2017' -- Or whatever FY you need current
    ) s1
WHERE s1.rn = 1

答案 1 :(得分:0)

澄清我先前的评论:(这可能太长,不能发表评论)

我假设ips表包含每个vendorID的多个付款日期。 那么我们可以将我们考虑的最大日期限制在所需范围内吗?

也许我还没有完全理解这个问题。

   SELECT ven.VendorID
        , ven.Name AS [Vendor Name]
        , inv.ReferenceNumber AS [Ref. No]
        , inv.InvoiceNumber AS [Invoice No]
        , inv.Payment AS Payment
        , SubMax.[Pay On Date]
   FROM inv
   INNER JOIN (SELECT MAX(ips.PayOnDateTime) AS [Pay On Date]
                    , VendorID
               FROM  inv
               LEFT JOIN ips 
                  ON ips.SourceID = inv.SourceID 
                 AND ips.InvoiceID = inv.InvoiceID
              -- Can we put it here? so that max can only be payondates in your fiscal year?
                 AND ips.PayOnDateTime BETWEEN @StartDate AND @EndDate  
               GROUP BY VendorID) SubMax 
      ON inv.VendorID = SubMax.VendorID 
   INNER JOIN ven 
      ON inv.SourceID = ven.SourceID 
     AND inv.VendorID = ven.VendorID
   LEFT JOIN ips 
      ON ips.SourceID = inv.SourceID 
     AND ips.InvoiceID = inv.InvoiceID
   WHERE FacilityID = 'HMC'
       --WHY HERE
       --AND SubMax.[Pay On Date] BETWEEN @StartDate AND @EndDate  
      AND inv.ReferenceNumber LIKE '__-____'
   ORDER BY ven.Name
          , SubMax.[Pay On Date]