如何从左连接中的嵌套子查询中检索列?

时间:2017-04-18 16:03:09

标签: sql-server join subquery nested-query

我有一个存储过程,我必须从嵌套的子查询中检索一列。我知道如果它只嵌套一次如何得到它,但对于我的这种情况,我需要显示的列是双嵌套的。

SELECT a.vendor,
a.last,
MaxInv
FROM 
    (
    SELECT vendor, day 
    FROM tblvendor) a

    LEFT JOIN (SELECT vendor, tblarinv.arinv, tblardetail.arddate
    Sum([MaxQty]*[ActualCost]) AS MaxInv,
    FROM tblarinv
    INNER JOIN tblardetail 
    ON tblarinv.id= tblardetail.id)    
group by a.vendor,a.last

在上面的例子中,我必须从左连接LEFT JOIN (SELECT vendor,tblarinv.arinv, tblardetail.arddate中检索两列。最初,select语句中只有供应商,但由于我需要tblarinv.arinv, tblardetail.arddate,我在左连接中的select语句中添加了它们。然后,当我尝试在第一个SELECT语句中添加此字段时,它不会识别出错误'多部分标识符无法绑定'。 有人可以帮我从这里出去吗?

以下是我编辑过的查询:

SELECT 
a.Vendor, 
,CASE WHEN sum(GP)<>0 THEN GP ELSE 0 END GP
,a.ThreeMonths
,CASE WHEN sum(GP)<>0 THEN GP/@WorkDaysElapsed ELSE 0 END AS AvgDailyGP
,CurrentInv
,MaxInv
,Inventory_Variance

FROM 
(Select Vendor, sum(GrossProfit) ThreeMonths, 
    (Select sum(GrossProfit) From dbo.MonthlySales with (nolock) Where EndOfMonth Between dateadd(m,-3,@First) and @First-1) as AllThreeMonths
    FROM MonthlySales with (nolock)
    Where EndOfMonth>=dateadd(m,-3,@First) 
    Group By Vendor
    Having sum(GrossProfit)<>0) a

LEFT JOIN (Select tblMaterial.Vendor, tblARDetail.ARInvoiceID, tblARDetail.ARInvoiceDetailID, tblARInv.ARInvoiceDate
,(Sum(SplitAmount))-(Sum((CASE WHEN SplitAmount<0 THEN -1*ABS([Quantity]) ELSE ABS([Quantity]) END)*dbo.fn_CalculatePrice_Decimal(tblARDetail.UnitCost,tblARDetail.ProductDiscountPct))) AS GP

            FROM tblARInv with (nolock)
            INNER JOIN tblARDetail with (nolock) ON tblARDetail.ARInvoiceID = tblARInv.ARInvoiceID
            INNER JOIN tblMaterial with (nolock) ON tblMaterial.MaterialID = tblARDetail.MaterialID
            INNER JOIN [dbo].[tblCust]
                ON [tblCust].[CustomerID] = [tblARInv].[CustomerID]
            Where tblARInv.Date>= '' + cast(Month(GetDate()) as varchar(2)) + '/1/' + cast(year(GetDate()) as varchar(4)) + ''
                AND [tblCust].[Status] != 8 --Internal
            Group By tblMaterial.Vendor, tblARDetail.ARInvoiceID, tblARDetail.ARInvoiceDetailID, tblARInv.ARInvoiceDate) 
            ThisMonth ON ThisMonth.Vendor=a.Vendor


Group By
a.Vendor
,GP
,a.ThreeMonths
,AllThreeMonths
,CurrentInv
,MaxInv
,Inventory_Variance
END

所以,我需要检索我在上面编辑的查询中添加的tblARDetail.ARInvoiceID, tblARDetail.ARInvoiceDetailID, tblARInv.ARInvoiceDate

1 个答案:

答案 0 :(得分:1)

您的示例查询存在很多问题,但第一部分是*如果*您不需要&#34; nest&#34;加入,不做。 (这是一些人从Microsoft Access中获取的坏习惯,你必须使用那种混乱)。

您的伪查询可以简化为以下内容:

select 
    v.vendor
  , v.last
  , sum(d.[MaxQty]*d.[ActualCost]) as MaxInv
from tblvendor v
  left join tblarinv i
    on v.vendor = i.vendor
  left join tblardetail d
    on i.id= d.id
group by v.vendor, v.last

根据您编辑过的问题,这些列看起来不是嵌套的,ThisMonth中的列已加入a

select 
    a.Vendor
  , case when sum(GP) <> 0 then GP else 0 end GP
  , a.ThreeMonths
  , case when sum(GP) <> 0 then GP / @WorkDaysElapsed else 0 end as AvgDailyGP
  , CurrentInv
  , MaxInv
  , Inventory_Variance
  /* Include the desired columns in the select */
  , ThisMonth.ARInvoiceID
  , ThisMonth.ARInvoiceDetailID
  , ThisMonth.ARInvoiceDate
from (
  select 
      Vendor
    , sum(GrossProfit) ThreeMonths
    , (
      select sum(GrossProfit)
      from dbo.MonthlySales with (nolock)
      where EndOfMonth between dateadd(month, - 3, @First) and @First - 1
      ) as AllThreeMonths
  from MonthlySales with (nolock)
  where EndOfMonth >= dateadd(month, - 3, @First)
  group by Vendor
  having sum(GrossProfit) <> 0
  ) a
left join (
  select 
       tblMaterial.Vendor
     , tblARDetail.ARInvoiceID
     , tblARDetail.ARInvoiceDetailID
     , tblARInv.ARInvoiceDate
     , (Sum(SplitAmount)) 
       - (Sum((case when SplitAmount < 0 then - 1 * ABS([Quantity]) else ABS([Quantity]) end) * dbo.fn_CalculatePrice_Decimal(tblARDetail.UnitCost, tblARDetail.ProductDiscountPct))) 
         as GP
  from tblARInv with (nolock)
    inner join tblARDetail with (nolock) 
     on tblARDetail.ARInvoiceID = tblARInv.ARInvoiceID
    inner join tblMaterial with (nolock) 
     on tblMaterial.MaterialID = tblARDetail.MaterialID
    inner join [dbo].[tblCust] 
       on [tblCust].[CustomerID] = [tblARInv].[CustomerID]
  where [tblCust].[Status] != 8 --Internal 
   -- and tblARInv.date >= '' + cast(Month(GetDate()) as varchar(2)) + '/1/' + cast(year(GetDate()) as varchar(4)) + ''
   /* easier way to get start of the month */
   and tblARInv.date >= dateadd(month, datediff(month, 0, getdate() )  , 0) 
  group by tblMaterial.Vendor
   , tblARDetail.ARInvoiceID
   , tblARDetail.ARInvoiceDetailID
   , tblARInv.ARInvoiceDate
  ) ThisMonth on ThisMonth.Vendor = a.Vendor
left join (
 select Vendor
  , Sum(case when [InStock] > [MaxQty] then [MaxQty] * [ActualCost] else [Instock] * [ActualCost] end) as CurrentInv
  , Sum([MaxQty] * [ActualCost]) as MaxInv
  , ((Sum(case when [InStock] > [MaxQty] then [MaxQty] * [ActualCost] else [Instock] * [ActualCost] end) / Sum(case when [MaxQty] * [ActualCost] <> 0 then [MaxQty] * [ActualCost] else 1 end)) - 0.75) / 0.75 as Inventory_Variance
 from tblMaterial with (nolock)
 where (((MaxQty) > 0))
 group by Vendor
 ) as Inventory on Inventory.Vendor = a.Vendor
group by 
    a.Vendor
  , GP
  , a.ThreeMonths
  , AllThreeMonths
  , CurrentInv
  , MaxInv
  , Inventory_Variance 
  /* Include the desired columns in the group by too */
  , ThisMonth.ARInvoiceID
  , ThisMonth.ARInvoiceDetailID
  , ThisMonth.ARInvoiceDate 
end

参考: