Sql 同一select语句中的两个日期/期间,并返回每个期间的数据

Sql 同一select语句中的两个日期/期间,并返回每个期间的数据,sql,sql-server,tsql,Sql,Sql Server,Tsql,好的,我有一段工作代码,通过位置、操作、异常和最终支出获取与美元视图相关的数据。这是在FYPeriod之前完成的。假设这个返回的11702财年是2016年8月。我还希望它返回到同一行,即11602财年,即2015年8月。我尝试过添加另一个加入,只是做了一个FYPeriod-100,但当然没有任何回报。以下是返回FYPeriod的工作代码 SELECT dbo.fiscalmonthyearstring(f.FYPeriod) As MonthYear, f.FYPeriod, c.SYSTEMP

好的,我有一段工作代码,通过位置、操作、异常和最终支出获取与美元视图相关的数据。这是在FYPeriod之前完成的。假设这个返回的11702财年是2016年8月。我还希望它返回到同一行,即11602财年,即2015年8月。我尝试过添加另一个加入,只是做了一个FYPeriod-100,但当然没有任何回报。以下是返回FYPeriod的工作代码

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'
我希望我已经正确地解释了这一点,如果没有,我会尝试这样做


假设您的所有筛选都是获取上一年数据所必需的,那么我们可以将您当前的查询封装在

;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重写为内联表值函数,则性能会更好

内联表值函数与标量函数参考:


当您在where中使用f时,为什么[Operations]f是一个左连接?它基本上是一个内部连接在[dbo].[AEExceptions]d的内部联接中使用[dbo].[location]b时,为什么[dbo].[location]b是一个左联接?能否从表中提供示例数据?你能举一个你想要的输出的例子吗?MSSMS是我正在使用的DBMS。我附加了一个当前输出,我需要的是另外两列,显示上一个FYPeriod的美元和单位@EdwardRusui如果我从左边更改联接,我的查询将不再输出任何东西。一直跑到它超时。另一方面,谢谢你的链接,改掉的坏习惯让人大开眼界…@Jeremy我更新了查询并移动了一点连接,因为你有WHERE f.PLActivity='Total producted',这实质上是将对操作的连接变成一个内部连接,我已将AEExceptions更改为使用vw_totalUSD.SystemPlant而不是Location.PlantId进行连接。尝试在不使用cte的情况下运行它,以查看是否获得原始结果,并尝试在不使用函数dbo.fiscalmonthyearstring的情况下运行它,以查看这对性能的影响。这些更改对主查询有效。但随着cte的增加,它正在复制主数据,而不是cte数据。如果需要,我可以附加一个屏幕截图。在进一步的调查中,除了每行改变的pyDollars之外,所有数据都在重复。@Jeremy您需要修改cte的自连接条件,以便获得py的正确匹配。没有看到样本表和数据,我只能猜测我更新了代码,只在systemplant、exceptions和spendingAcct不为null且不匹配时获取上一年的美元。