将2个复杂查询合并为1

时间:2018-02-27 18:25:16

标签: sql sql-server sql-server-2016

我想弄清楚是否有办法将这两个查询合并为一个查询。我已经遇到了我所知道的极限,无法弄清楚这是否可行。

这是第一个获得每个地点(一个月)每天销售额的查询:

if object_id('tempdb..#LY_Data') is not null drop table #LY_Data
select  
    [LocationId]            = ri.LocationId,
    [LY_Date]               = convert(date, ri.ReceiptDate),
    [LY_Trans]              = count(distinct ri.SalesReceiptId),
    [LY_SoldQty]            = convert(money, sum(ri.Qty)),
    [LY_RetailAmount]       = convert(money, sum(ri.ExtendedPrice)),
    [LY_NetSalesAmount]     = convert(money, sum(ri.ExtendedAmount))
into #LY_Data
from rpt.SalesReceiptItem ri
join #Location l
    on ri.LocationId = l.Id
where ri.Ignored = 0
    and ri.LineType = 1 /*Item*/
    and ri.ReceiptDate between @_LYDateFrom and @_LYDateTo
group by 
    ri.LocationId, 
    ri.ReceiptDate


然后第二个查询根据每个月的总销售额(稍后使用)计算比率:

if object_id('tempdb..#LY_Data2') is not null drop table #LY_Data2
select 
    [LocationId]            = ly.LocationId,
    [LY_Date]               = ly.LY_Date,
    [LY_Trans]              = ly.LY_Trans,
    [LY_RetailAmount]       = ly.LY_RetailAmount,
    [LY_NetSalesAmount]     = ly.LY_NetSalesAmount,
    [Ratio]                 = ly.LY_NetSalesAmount / t.MonthlySales
into #LY_Data2
from ( 
        select
            [LocationId]        = ly.LocationId,
            [MonthlySales]      = sum(ly.LY_NetSalesAmount)
        from #LY_Data ly
        group by
            ly.LocationId
) t
join #LY_Data ly
    on t.LocationId = ly.LocationId


我已经尝试在第二个查询group-by子句中使用第一个查询作为子查询,但是这不允许我在最外面的select语句中选择那些列(多部分标识符不能用于#t; t约束)。

除了在第二个查询结尾处将第一个查询放入join子句时也存在同样的问题。

这可能是我所遗漏的东西,但我仍然对SQL很陌生,所以任何帮助或指向正确方向的指针都会非常感激! :)

2 个答案:

答案 0 :(得分:3)

您可以尝试使用Common Table Expression (CTE)window function

if object_id('tempdb..#LY_Data') is not null drop table #LY_Data

;with
    cte AS
    (
        select  
            [LocationId]            = ri.LocationId,
            [LY_Date]               = convert(date, ri.ReceiptDate),
            [LY_Trans]              = count(distinct ri.SalesReceiptId),
            [LY_SoldQty]            = convert(money, sum(ri.Qty)),
            [LY_RetailAmount]       = convert(money, sum(ri.ExtendedPrice)),
            [LY_NetSalesAmount]     = convert(money, sum(ri.ExtendedAmount))
        from rpt.SalesReceiptItem ri
        join #Location l
            on ri.LocationId = l.Id
        where ri.Ignored = 0
            and ri.LineType = 1 /*Item*/
            and ri.ReceiptDate between @_LYDateFrom and @_LYDateTo
        group by 
            ri.LocationId, 
            ri.ReceiptDate
    )

select
    [LocationId]        = cte.LocationId,
    [LY_Date]           = cte.LY_Date,
    ...
    [Ratio]             = cte.LY_NetSalesAmount / sum(cte.LY_NetSalesAmount) over (partition by cte.LocationId)
into #LY_Data
from cte

sum(cte.LY_NetSalesAmount) over (partition by cte.LocationId)为您提供每个locationId的总和。代码假设此总和始终为非零。否则,将发生0分频错误。

答案 1 :(得分:0)

似乎你需要做的就是在第一个查询中计算ratio

您可以使用相关子查询执行此操作。

SELECT
...
convert(money, sum(ri.ExtendedAmount)/(SELECT sum(ri2.ExtendedAmount)
                                       FROM rpt.SalesReceiptItem ri2
                                       WHERE ri2.LocationId=ri.LocationId
                                      )
) AS ratio  --extended amount/total extended amount for this location