在同一个select语句中的两个日期/期间和每个期间的返回数据

问题描述:

好的,我有一段代码可以根据位置,操作,异常和最终消费获取与美元视图相关的数据。这由FYPeriod完成。可以说,这返回FYPeriod 11702这是2016年8月。我也希望它在同一行FYPeriod 11602是2015年8月返回。我尝试添加另一个连接,只是做一个(FYPeriod - 100),但当然这没有返回。这是返回FYPeriod的工作代码。在同一个select语句中的两个日期/期间和每个期间的返回数据

SELECT dbo.fiscalmonthyearstring(f.FYPeriod) As MonthYear, f.FYPeriod, c.SYSTEMPLANT, e.SpendingAcct, 
c.DOLLARS, f.Data AS Units, d.exceptions, f.PLActivity 
    FROM [vw_TotalDollars] c 
    LEFT JOIN [dbo].[location] b ON b.PlantId = c.SYSTEMPLANT 
    LEFT JOIN [Operations] f ON f.FYPeriod = c.PST 
AND f.location = b.location 
    JOIN [dbo].[aexceptions] d ON b.PlantId = d.Id 
AND d.acc = c.ACCN 
AND exceptions IN ('Z2', 'X2' , 'Z7' , 'X7') 
    LEFT JOIN [dbo].[Spending] e ON e.SpendingId = d.SpendingId 
    WHERE f.PLActivity = 'Total Produced' 

我希望我已经解释正确,如果没有,我会尽力这样做。

Current output

+0

为什么'[操作F的''一个左join'当你在'where'中使用'f'基本上使它成为'inner join'? - 为什么是'[dbo]。[位置] b'是一个'左连接',当你在'[dbo]的'inner join'中使用它时[aexceptions] d'? – SqlZim

+0

[踢坏的习惯:使用像(a,b,c)或(t1,t2,t3)这样的表别名 - Aaron Bertrand](http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/08 /bad-habits-to-kick-using-table-aliases-like-abc-or-t1-t2-t3.aspx) – SqlZim

+0

您能否提供表格中的示例数据?你能举一个你想要的输出的例子吗? – KindaTechy

假设所有的过滤是必要的也得到了前一年的数据,我们可以在一个common table expression包你当前的查询,以便我们可以引用它反对它,像这样:

;with cte as (
    select 
     o.fyperiod 
    , td.systemplant 
    , s.SpendingAcct 
    , td.dollars 
    , o.[Data] as Units 
    , ae.exceptions 
    , o.plactivity 
    from [vw_TotalDollars] td 
    inner join [Operations] o 
     on o.fyperiod = td.pst 
    and o.plactivity = 'Total Produced' 
    left join [dbo].[location] l 
     on l.PlantId = td.systemplant 
    and l.location = o.location 
    left join [dbo].[aexceptions] ae 
     on ae.Id = td.systemplant 
    and ae.acc = td.accn 
    and ae.exceptions in ('Z2','X2','Z7','X7') 
    left join [dbo].[Spending] s 
     on s.SpendingId = ae.SpendingId 
) 
select 
    cte.FyPeriod 
    --, MonthYear = dbo.fiscalmonthyearstring(cte.fyperiod) 
    , cte.SystemPlan 
    , cte.SpendingAcct 
    , cte.Dollars 
    , cte.Units 
    , cte.Exceptions 
    , cte.Plactivity 
    --, pyMonthYear = dbo.fiscalmonthyearstring(py.fyperiod) 
    , pyDollars = py.Dollars 
    , pyUnits  = py.Units 
from cte 
    left join cte as py 
    on py.fyperiod  = cte.fyperiod-100 
    and py.systemplant = cte.systemplant 
    and py.exceptions = cte.exceptions 
    and py.SpendingAcct = cte.SpendingAcct 

注意:如果重写为内联表值函数,那么标量函数dbo.fiscalmonthyearstring()的性能会更好。

内联表值函数VS标量函数引用:

+0

如果我从左侧更改连接,我的查询不再输出任何内容。只是运行,直到它超时。在一个侧面说明谢谢你的链接,不良习惯踢是一个大开眼界... – Jeremy

+0

@Jeremy我已经更新了查询并移动了一些联接,因为你有'WHERE f.PLActivity ='Total Produced' ',这基本上使得连接到'操作'一个'内部连接',我已经改变'aexceptions'使用'vw_TotalDollars.SystemPlant'而不是'Location.PlantId'连接。尝试在没有'cte'的情况下运行它,看看你是否得到了原始结果,并尝试运行它,而不使用函数'dbo.fiscalmonthyearstring()'以查看它是如何影响性能的。 – SqlZim

+0

这些更改适用于主要查询。但随着cte的增加,它正在复制主要数据而不是cte数据。如果需要,我可以附上一个屏幕截图。 – Jeremy