基于最近日期的自我T-SQL JOIN表

时间:2016-10-21 11:06:38

标签: sql tsql datetime time inner-join

提前感谢您阅读!

我想回答的问题是:“制造零件的成本是多少?”我们通过将原材料坯料加工成金属零件来制造。最终零件销售给客户,废料从废料出售到废料场。

出于业务/ ERP配置原因,我们的废料供应商被列为客户,我们像其他客户一样向他发送“零件”。这些虚拟零件仅适用于我们使用的每种金属合金,因此我们使用的每种合金都有一个假废料零件。每当我们填满废料箱时就会发货,因此没有明确的时间间隔。

我正在尝试将真实零件的发货日期与真实客户连接到同一合金的最接近废料日期。然后,我可以获得每磅我们支付的废品价值,并将其包含在我们制造的零件的收入中。如果我可以要求这个世界,那么知道如何在装运真实零件之前或之后立即抓取废料将是有帮助的 - 我相信管理层会多次改变他们的想法,如果他们想要使用'在'或'之前'或'之后。

我尝试过其他解决方案但无法让它们发挥作用。我哭了叔叔,我根本无法让它工作....我们的ERP使用的Web SQL界面声称它是T-SQL ...感谢你阅读这篇文章!

我希望输出看起来像是:

 Customer  Part     Price   Alloy  Weight_Lost  Scrap_Value   Ship_Date  
 ABC       Widget1  99.99   C182    63            2.45         10-01-2016

这是最简单的我可以将表格简化为:

   SELECT
    tbl_Regular_Sales.Customer
    tbl_Regular_Sales.Part
    tbl_Regular_Sales.Price
    tbl_Regular_Sales.Alloy
    tbl_Regular_Sales.Weight_Lost
    tbl_Scrap_Sales.Price AS 'Scrap_Value'
    tbl_Regular_Sales.Ship_Date
   FROM
    (SELECT P.Part
           ,P.Alloy
           ,P.Price
           ,S.Ship_Date
           ,S.Customer
    FROM    Part AS P
    JOIN    S AS S
    ON      S.Part_Key = P.Part_Key
    WHERE   Shipper.Customer = 'Scrap_Yard'
    ) AS tbl_Scrap_Sales
    JOIN
       (SELECT  P.Part
               ,P.Weight_Lost
               ,P.Alloy
               ,P.Price
               ,S.Ship_Date
               ,S.Customer
       FROM    Part AS P
       JOIN    S AS S
       ON      S.Part_Key = P.Part_Key
       WHERE   Shipper.Customer <> 'Scrap_Yard' ) AS tbl_Regular_Sales
    ON
    tbl_Regular_Sales.Alloy = tbl_Scrap_Sales.Alloy
    AND   <Some kind of date JOIN to get the closest scrap shipment value>

1 个答案:

答案 0 :(得分:1)

这样的事情可以解决问题:

WITH cteScrapSales AS (
    SELECT 
        P.Alloy 
        ,P.Price
        ,S.Ship_Date
    FROM Part AS P
    JOIN Shipper AS S ON S.Part_Key = P.Part_Key
    WHERE S.Customer = 'Scrap_Yard'
), cteRegularSales AS (
    SELECT 
        P.Part_Key
        ,P.Part
        ,P.Weight_Lost
        ,P.Alloy
        ,P.Price
        ,S.Ship_Date
        ,S.Customer
    FROM Part AS P
    JOIN Shipper AS S ON S.Part_Key = P.Part_Key
    WHERE S.Customer <> 'Scrap_Yard'
)
SELECT
        C.Customer
        ,C.Part
        ,C.Price
        ,C.Alloy
        ,C.Weight_Lost
        ,C.Scrap_Value
        ,C.Ship_Date
    FROM (
        SELECT R.*, S.Price AS Scrap_Value, ROW_NUMBER() OVER (PARTITION BY R.Part_Key ORDER BY DATEDIFF(SECOND, R.Ship_Date, S.Ship_Date)) ix
        FROM cteRegularSales R 
        JOIN cteScrapSales S ON S.Allow = R.Allow AND S.Ship_Date > R.Ship_Date
    ) AS C
    WHERE C.ix = 1;