我使用子查询编写代码,但速度太慢。我正在寻找一种可以优化此查询过程的解决方案。它旨在返回6列 - 采购订单编号,采购订单行编号,每个采购订单行的金额,每个采购订单编号的采购单行数,每个采购订单编号的行金额总和,每个采购订单编号按行数分类。下面是我写的示例表和实际查询。非常感谢您的帮助!
|PO NUMBER |PO LINE|LINE AMOUNT|TOTAL PO LINES|TOTAL PO AMOUNT|TOTAL PO GROUP|
|1721574 | 1 | 10.76 | 1 | 10.76 | $0-100 |
|1722154 | 1 | 30.00 | 1 | 30.00 | $0-100 |
|1723538 | 1 | 15.97 | 4 | 65.63 | $0-100 |
|1723538 | 2 | 11.23 | 4 | 65.63 | $0-100 |
|1723538 | 3 | 15.97 | 4 | 65.63 | $0-100 |
|1723538 | 4 | 22.46 | 4 | 65.63 | $0-100 |
|1723877 | 1 | 15.70 | 1 | 15.70 | $0-100 |
查询
select ph.ponumber,
pl.poline,
pl.polinebasemerchamount,
(select count(pl2.poline)
from dbo.polineflat as pl2
inner join dbo.poheader as ph2
on ph2.pokey = pl2.pokey
where ph2.pokey = ph.pokey
group by ph2.ponumber),
(select sum(pl2.polinebasemerchamount)
from dbo.polineflat as pl2
inner join dbo.poheader as ph2
on ph2.pokey = pl2.pokey
where ph2.pokey = ph.pokey
group by ph2.ponumber),
(select case
when sum(pl2.PoLineBaseMerchAmount) between 0 and 100 then '$0-100'
when sum(pl2.polinebasemerchamount) between 101 and 500 then '$101-500'
when sum(pl2.polinebasemerchamount) between 501 and 1000 then '$501-1000'
else '1000+' end
from dbo.polineflat as pl2
inner join dbo.poheader as ph2
on ph2.pokey = pl2.pokey
where ph2.pokey = ph.pokey
group by ph2.ponumber)
from dbo.poheader as ph
inner join dbo.polineflat as pl on ph.pokey = pl.pokey
答案 0 :(得分:1)
可以使用def put(self, request, *args, **kwargs):
serializer = self.serializer_class(self.get_object(), data=request.data, partial=True)
if serializer.is_valid():
instance = serializer.save()
# Generate a new token
payload = jwt_payload_handler(instance)
token = jwt.encode(payload, settings.SECRET_KEY)
response = JsonResponse({'token': token.decode('unicode_escape')})
response.status = 200
return response
else:
response = JsonResponse({'errors': serializer.errors})
response.status = 500
return response
将三个sub-queries
合并为一个查询。使用Cross Apply
优于相关子查询的一个优点是它可以在Cross Apply
列表中返回多个列
select
注意:我删除了子查询中的SELECT ph.ponumber,
pl.poline,
pl.polinebasemerchamount,
oa.poline_count,
oa.polinebasemerchamount_sum,
CASE
WHEN oa.polinebasemerchamount_sum BETWEEN 0 AND 100 THEN '$0-100'
WHEN oa.polinebasemerchamount_sum BETWEEN 101 AND 500 THEN '$101-500'
WHEN oa.polinebasemerchamount_sum BETWEEN 501 AND 1000 THEN '$501-1000'
ELSE '1000+'
END AS Range
FROM dbo.poheader AS ph
CROSS Apply (SELECT Count(pl2.poline) AS poline_count,
Sum(pl2.polinebasemerchamount) AS polinebasemerchamount_sum
FROM dbo.polineflat AS pl2
WHERE pl2.pokey = ph.pokey) oa
,因为它应该没用,否则会在原始查询中抛出错误
更新:要进一步改进查询,请创建以下Group By
Non clustered indexes
答案 1 :(得分:1)
我会计算一次总和,然后在父查询中进行处理:
SELECT ponumber, poline, polinebasemerchamount, polineCount, polineFlatSum,
CASE
WHEN polineFlatSum between 0 and 100 then '$0-100'
WHEN polineFlatSum between 101 and 500 then '$101-500'
WHEN polineFlatSum between 501 and 1000 then '$501-1000'
ELSE '1000+'
END AS polineFlatSumString
from
(
select ph.ponumber,
pl.poline,
pl.polinebasemerchamount,
(select count(pl2.poline)
from dbo.polineflat as pl2
inner join dbo.poheader as ph2
on ph2.pokey = pl2.pokey
where ph2.pokey = ph.pokey
group by ph2.ponumber) AS polineCount,
(select sum(pl2.PoLineBaseMerchAmount)
from dbo.polineflat as pl2
inner join dbo.poheader as ph2
on ph2.pokey = pl2.pokey
where ph2.pokey = ph.pokey
group by ph2.ponumber) AS polineFlatSum,
from dbo.poheader as ph
inner join dbo.polineflat as pl on ph.pokey = pl.pokey
) T
答案 2 :(得分:0)
试试这个......
select ph2.ponumber,
pl2.poline,
pl2.polinebasemerchamount,
count(pl2.poline) ,
sum(pl2.polinebasemerchamount) ,
case when sum(pl2.PoLineBaseMerchAmount) between 0 and 100 then '$0-100'
when sum(pl2.polinebasemerchamount) between 101 and 500 then '$101-500'
when sum(pl2.polinebasemerchamount) between 501 and 1000 then '$501-1000'
else '1000+' end
from dbo.poheader as ph2
inner join dbo.polineflat as pl2
on ph.pokey = pl.pokey
inner join dbo.polineflat as pl2
on ph.pokey = pl2.pokey
group by ph2.ponumber,
pl2.poline,
pl2.polinebasemerchamount
答案 3 :(得分:0)
看起来你正在通过使用选择
进行分组select ph.ponumber,
pl.poline,
pl.polinebasemerchamount,
count(pl.poline) as total_count,
sum(pl.polinebasemerchamount) as total_sum,
case when sum(pl.PoLineBaseMerchAmount) between 0 and 100 then '$0-100'
when sum(pl.polinebasemerchamount) between 101 and 500 then '$101-500'
when sum(pl.polinebasemerchamount) between 501 and 1000 then '$501-1000'
else '1000+' end as total_group
from dbo.poheader as ph
inner join dbo.polineflat as pl
on ph.pokey = pl.pokey
group by ph.ponumber, pl.poline, pl.polinebasemerchamount
答案 4 :(得分:0)
在这些情况下,我实际上使用#temp表。我发现它们在性能上要好得多,我可以更好地控制我想要的结果。它也更容易理解(至少对于我和其他阅读它们的人来说)。我回答这篇文章的目的是帮助您利用这种类型的编码。而不是直接给你答案,你可以复制和粘贴,然后点击F5。
注意:您可以随意命名对您有意义的临时表。您还可以使用LEFT JOIN / RIGHT JOIN来获取dbo.poheader中的所有值,并查看值与您的#temp表匹配。您可能需要切换ID&temp / temp表以适合您需要的结果。我希望这可以帮助你理解。
--Insert Subquery 1 into a #temp1
select count(pl2.poline) as Count1, ph2.ponumber
Into #temp1
from dbo.polineflat as pl2
inner join dbo.poheader as ph2
on ph2.pokey = pl2.pokey
where ph2.pokey = ph.pokey
group by ph2.ponumber)
--Insert Subquery 2 into #temp2
select sum(pl2.polinebasemerchamount) as Sum1, ph2.ponumber
into #temp2
from dbo.polineflat as pl2
inner join dbo.poheader as ph2
on ph2.pokey = pl2.pokey
where ph2.pokey = ph.pokey
group by ph2.ponumber
--Insert Subquery 3 into #temp3. Pull pl2.polinebasemerchant from #temp2
select case
when sum(#temp2.PoLineBaseMerchAmount) between 0 and 100 then '$0-100'
when sum(#temp2.polinebasemerchamount) between 101 and 500 then'$101-500'
when sum(#temp2..polinebasemerchamount) between 501 and 1000 then '$501-1000'
else '1000+' end 'DollarAmounts',ph2.ponumber
into #temp3
from dbo.polineflat as pl2
inner join dbo.poheader as ph2
on ph2.pokey = pl2.pokey
where ph2.pokey = ph.pokey
group by ph2.ponumber
-- Select here with the temp table groups
select ph.ponumber,
pl.poline,
pl.polinebasemerchamount,
#temp1.Count1,
#temp2.Sum1,
#temp3.DollarAmounts
from dbo.poheader as ph
join dbo.polineflat as pl on ph.pokey = pl.pokey
--join your temp tables here
Join #temp1 on #temp1.ponumber = ph.ponumber
join #temp2 on #temp2.ponumber = ph.ponumber
join #temp3 on #temp3.ponumber = ph.ponumber
TRUNCATE TABLE #temp1
TRUNCATE TABLE #temp2
TRUNCATE TABLE #temp3