2017-04-18 231 views
0

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

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

该查询看起来不正确的。 'last'从哪里来?你在'a'的连接和在'left join'后的未命名派生表在哪里?你为什么要在未命名的派生表之外进行聚合而不是在其内部进行聚合?你的派生表中有'vendor'来自哪里? – SqlZim

+0

这里是一个开始的好地方。 http://spaghettidba.com/2015/04/24/how-to-post-a-t-sql-question-on-a-public-forum/ –

+0

@SqlZim:我的查询是复杂,所以我想给简单的例子。对不起,我会尝试正确编辑我的代码。 – toofaced

回答

1

有很多与您的示例查询的问题,但第一部分是,如果*您不需要“鸟巢”加入,不这样做。 (这是一些人从微软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 

参考:

+0

我在帖子中编辑了我的查询。感谢您的伪查询;然而,它是我的问题中的双重嵌套查询。根据xQbert,如果它不止一个级别,它就不能被访问。 – toofaced

+0

@toofaced更新了我的答案,以便用您的实际查询编辑 – SqlZim

+0

是的,当我再次浏览他们时,我意识到了这一点。谢谢你的帮助。 – toofaced