我有一个庞大的查询,我想向其中添加左联接。 添加的内容已被注释掉。
主查询运行<4秒,32,000行。
注释的部分运行时间少于1秒,共51,000行。
但是,当我将它们组合在一起时,即加入第二个查询,整个过程将在15秒内完成。
原始查询中已经有2个大规模联接(均为50,000行),所以我不知道为什么这种联接很特殊。
PS:我可能还在做其他次优的事情,请批评。
select
*,
case
when t2.status = 1 and t2.price > t2.buyprice then round((t2.price - t2.buyprice) * 0.04, 2)
when t2.status = 2 and t2.price > t2.buyprice then round((t2.price - t2.buyprice) * 0.03, 2)
when t2.status = 3 and t2.price > t2.buyprice then round((t2.price - t2.buyprice) * 0.02, 2)
when t2.status = 4 and t2.price > t2.buyprice then round((t2.price - t2.buyprice) * 0.01, 2)
else 0
end as bonus
from (
select *,
case
when t1.gratis = 1 then 10
when t1.price_vat = 0 or t1.price = 0 then
case
when t1.stock > 0 or soldLast180DaysQty > 0 then -1
when t1.stock = 0 then 12
end
when t1.buyprice = 0 then
case
when t1.stock > 0 then -1
when t1.stock = 0 then 12
end
when soldLast180DaysQty < 0 then 1
when t1.age_days < 60 then 9
when t1.last_import <= 180 then
case
when t1.soldLast180DaysQty <= t1.stock then 0
when t1.soldLast180DaysQty > t1.stock then 7
when t1.stock = 0 then 5
end
when t1.last_import >= 180 and t1.stock = 0 then
case
when soldLast180DaysQty > 0 then 10
when soldLast180DaysQty = 0 then 11
end
when t1.last_import >= 180 then
case
when t1.soldLast180DaysQty / nullif(t1.stock + t1.soldLast180DaysQty, 0) < 0.3 and t1.stock_retail / t1.stock >= 0.9 then 5
when t1.soldLast180DaysQty / nullif(t1.stock + t1.soldLast180DaysQty, 0) between 0 and 0.1 then 1
when t1.soldLast180DaysQty / nullif(t1.stock + t1.soldLast180DaysQty, 0) between 0.1 and 0.2 then 2
when t1.soldLast180DaysQty / nullif(t1.stock + t1.soldLast180DaysQty, 0) between 0.2 and 0.3 then 3
when t1.soldLast180DaysQty / nullif(t1.stock + t1.soldLast180DaysQty, 0) between 0.3 and 0.4 then 4
when t1.soldLast180DaysQty / nullif(t1.stock + t1.soldLast180DaysQty, 0) between 0.4 and 0.7 then 0
when t1.soldLast180DaysQty / nullif(t1.stock + t1.soldLast180DaysQty, 0) >= 0.9 then 6
when t1.soldLast180DaysQty / nullif(t1.stock + t1.soldLast180DaysQty, 0) between 0.8 and 0.9 then 7
when t1.soldLast180DaysQty / nullif(t1.stock + t1.soldLast180DaysQty, 0) between 0.7 and 0.8 then 8
end
end as status,
round(t1.soldLast180DaysQty / nullif(t1.stock + t1.soldLast180DaysQty, 0) * 100, 0) as ratio
from (
select
si.anqid id,
CAST(rtrim(si.acident) as nvarchar(7)) as code,
CAST(rtrim(si.acname) as nvarchar(100)) as name,
si.anvat as vat,
si.ansaleprice as price_vat,
round(si.anrtprice, 2) as price,
cenovnik.clientPrice, -- <---------------------- This part
round(si.anbuyprice, 2) as buyprice,
concat(round(anpricesupp, 2), ' ', acpurchcurr) as fakturna,
round(si.anrtprice - si.anbuyprice, 2) as profit,
case
when si.anrtprice is not null and si.anrtprice > 0 and si.anbuyprice is not null and si.anbuyprice > 0
then round((si.anrtprice / si.anbuyprice - 1) * 100, 0)
end as margin,
cast(si.acfieldsa as nvarchar(12)) as [group],
cast(rtrim(si.acClassif2) as nvarchar(16)) as category,
cast(rtrim(ss.acsubject) as nvarchar(7)) as supplier_code,
cast(left(ss.acname2, 30) as nvarchar(30)) as supplier_name,
rtrim(si.acclassif) as rebate,
si.anFieldNA as webActive,
si.anfieldNF as gratis,
case
when si.acpicture is not null then 'true'
else 'false'
end as picture,
isnull((select sum(anstock) from the_stock where acident = si.acident and acwarehouse = '00051'), 0) as stock_warehouse,
isnull((select sum(anstock) from the_stock where acident = si.acident and acwarehouse <> '00051'), 0) as stock_retail,
isnull((select sum(anstock) from the_stock where acident = si.acident), 0) as stock,
isnull((select sum(anReserved) from the_stock where acident = si.acident), 0) as stock_reserved,
isnull((select sum(anvalue) from the_stock where acident = si.acident), 0) as stock_value,
(
select isnull(datediff(day, max(m.addate), getdate()), 9999)
from the_moveitem mi
left join the_move m
on mi.ackey = m.ackey
where mi.acident = si.acident and m.acDocType in ('1900', '1000', '6800', '1A00')
) as last_import,
isnull(round(soldLast180Days.soldLast180DaysQty, 0), 0) soldLast180DaysQty,
isnull(round(soldLast180Days.soldLast180DaysCogs, 0), 0) soldLast180DaysCogs,
isnull(round(soldLast180Days.soldLast180DaysRevenue, 0), 0) soldLast180DaysRevenue,
isnull(round(soldLast180Days.soldLast180DaysProfit, 0), 0) soldLast180DaysProfit,
datediff(day, si.adtimeins, getdate()) as age_days
from the_setitem si
/*
left join (
SELECT
si.acident sku,
case
when dogovoren.anPrice is null and matrica.anRebate is null then si.anRTPrice
when dogovoren.anPrice is not null then dogovoren.anPrice
when dogovoren.anPrice is null then si.anRTPrice * (1 - matrica.anRebate/100)
end as clientPrice
FROM tHE_SetItem si
left join (
select acident, anPrice
from vHE_SetSubjPriceItemExtToday
where acsubject = '1111'
) dogovoren
on dogovoren.acident = si.acident
left join (
select acClassif, anRebate
from vHE_SetSubjTypePriceCateg
where acSubjType = (select acsubjtypebuyer from tHE_SetSubj where acsubject = '1111')
) matrica
on si.acClassif = matrica.acClassif
) cenovnik
on cenovnik.sku = si.acident
*/
left join tHE_SetSubj ss
on ss.acsubject = si.acsupplier
left join (
select
mi.acident,
sum(mi.anQty) soldLast180DaysQty,
sum(mi.anQty * mi.anStockPrice) soldLast180DaysCogs,
sum(mi.anPVVATBase) soldLast180DaysRevenue,
sum(mi.anPVVATBase - mi.anQty * mi.anStockPrice) soldLast180DaysProfit
from the_moveitem mi
left join the_move m
on m.ackey = mi.ackey
where m.acDocType in ('3000', '3050', '3190', '3800', '3550', '3X10', '3950', '3500', '3510', '6700', '3A00', '3210', '3220', '3230', '3240', '3450', '3250', '3260', '3270', '3540', '3460', '3280', '3290', '3310', '3320', '3440', '3330', '3340', '3350', '3360', '3370', '3380', '3390', '3410', '3470', '3420', '3430', '3480', '3490', '3520', '3530', '3560', '3610', '2540', '2740', '2730'
) and m.addate >= getdate() - 180
group by mi.acident
) soldLast180Days
on soldLast180Days.acIdent = si.acident
) t1
) t2
where
t2.status < 11
order by
t2.status asc,
t2.stock_value desc
如果相关,我正在使用SQL Server。
答案 0 :(得分:1)
并不是一个真正的答案-但是当我遇到这个问题时,我只是创建了临时表。在SQL Server中,为表名加上#前缀,会话结束后它们将被删除。
您可能将嵌套表t1理解为临时表#t1
CREATE TABLE #t1 (id INT, code NVARCHAR(7), etc...)
INSERT INTO #t1
select
si.anqid id,
CAST(rtrim(si.acident) as nvarchar(7)) as code,
CAST(rtrim(si.acname) as nvarchar(100)) as name,
etc..
SELECT * FROM .... #t1 ...
将所有对t1的引用替换为#t1