I want to get the result set in the descending range order. Below is my Query
select quantity_range as quantity_range, count(*) as number_of_items,
sum(amount) as total_amount,
from (
select *,case
when quantity between 0 and 500 then '<=500'
when quantity between 501 and 525 then '501-525'
when quantity between 526 and 550 then '526-550'
when quantity between 551 and 575 then '551-575'
when quantity between 576 and 600 then '576-600'
when quantity between 601 and 625 then '601-625'
when quantity between 626 and 650 then '626-650'
when quantity between 651 and 675 then '651-675'
when quantity between 676 and 700 then '676-700'
when quantity between 701 and 725 then '701-725'
when quantity between 726 and 750 then '726-750'
else '>750' end as quantity_range
from Sales )
group by quantity_range order by quantity_range;
I want my Result set like:
<=500 100 100000.00
600-625 10 5000.00
>700 25 25000.00
How to get this ordering? If i give Order By clause then >700 coming at 2nd position.
Use RIGHT to get last number from string:
select quantity_range as quantity_range, count(*) as number_of_items,
sum(amount) as total_amount
from (
select *,case
when quantity between 0 and 500 then '<=500'
when quantity between 501 and 525 then '501-525'
when quantity between 526 and 550 then '526-550'
when quantity between 551 and 575 then '551-575'
when quantity between 576 and 600 then '576-600'
when quantity between 601 and 625 then '601-625'
when quantity between 626 and 650 then '626-650'
when quantity between 651 and 675 then '651-675'
when quantity between 676 and 700 then '676-700'
when quantity between 701 and 725 then '701-725'
when quantity between 726 and 750 then '726-750'
else '>750' end as quantity_range
from Sales ) as sub
group by quantity_range
order by RIGHT(quantity_range,3);
SqlFiddleDemo
Related
Trying to get the folliwng names as well as a column summarizing the payment + the 2 consecutive payments for the customer, listed chronologically.
First time using the lead funciton, and managed to make it work, but with the sum() I get an error:
SQL Error [42803]: ERROR: column "p.payment_id" must appear in the GROUP BY clause or be used in an aggregate function
Position: 11
select
p.payment_id,
c.first_name,
c.last_name,
p.amount,
lead(sum(amount),3)over(partition by p.payment_id order by amount)as sum_pay
from payment p
left join customer c on c.customer_id = p.customer_id;
Can anyone give any tips as to where the problem lies?
p.id c.id s.id r.id amount payment_date
17503 341 2 1520 7.99 2007-02-15 22:25:46.996
17504 341 1 1778 1.99 2007-02-16 17:23:14.996
17505 341 1 1849 7.99 2007-02-16 22:41:45.996
17506 341 2 2829 2.99 2007-02-19 19:39:56.996
17507 341 2 3130 7.99 2007-02-20 17:31:48.996
17508 341 1 3382 5.99 2007-02-21 12:33:49.996
17509 342 2 2190 5.99 2007-02-17 23:58:17.996
17510 342 1 2914 5.99 2007-02-20 02:11:44.996
17511 342 1 3081 2.99 2007-02-20 13:57:39.996
17512 343 2 1547 4.99 2007-02-16 00:10:50.996
17513 343 1 1564 6.99 2007-02-16 01:15:33.996
17514 343 2 1879 0.99 2007-02-17 01:26:00.996
17515 343 2 1922 0.99 2007-02-17 04:32:51.996
17516 343 2 2461 6.99 2007-02-18 18:26:38.996
Trying to get an additional row of customer and sum payment + 2 consecutive payments
I have this query calculating how many products I have to produce to serve my pending orders and the components I need to produce them.
select
l.codart as SKU, --final product
e.codartc as Component, --piece of final product
e.unicompo, --Components needed for each SKU
l1.SKU_pending - s.SKU_STOCK as "SKU to produce",
s2.C_STOCK as "Component stock",
s2.C_STOCK - sum((l1.SKU_pending - s.SKU_STOCK) * e.unicompo)
over (partition by e.codartc order by l.codart) as "Component stock after producing"
from linepedi l --table with sales orders
left join escandallo e on e.codartp = l.codart --table with SKU components
inner join (select l1.codart, sum(l1.unidades - l1.uniservida - l1.unianulada) as "SKU_pending" --pending sales. I called it from a subquery so I don't have to repeat the calculation each time I need it
from linepedi l1
where (l1.unidades - l1.uniservida - l1.unianulada) > 0
group by l1.codart) l1 on l1.CODART = l.codart
left join (select s.codart, sum(s.unidades) as "SKU_STOCK"
from __STOCKALMART s
group by s.codart) s on s.codart = l.codart
left join (select s.codart, sum(s.unidades) as "C_STOCK"
from __STOCKALMART s
group by s.codart) s2 on s2.codart = e.codartc
where l1.SKU_pending - s.SKU_STOCK > 0
group by l.codart, e.codartc, e.unicompo, l1.SKU_pending, s.SKU_STOCK, s2.C_STOCK
order by l.codart
Query returns next table:
SKU
Component
unicompo
SKU to produce
Component stock
Component stock after producing
20611
286
1
50
2021
1971
20611
329
1
50
2759
2709
20611
ARTZD031
1
50
643
593
220178
ARTZD027
1
384
477
93
220178
SICBB005
1
384
845
461
220178
265
1
384
894
510
220185
265
1
200
894
310
220185
SICBB005
1
200
845
261
220185
ARTZD028
1
200
71
-129
220192
ARTZD029
1
200
364
164
220192
SICBB005
1
200
845
61
220192
265
1
200
894
110
When Component stock after producing returns less than 0, I don't want it to substract the SKU to produce, but the mininum Component stock for that SKU, while "saving" this value for the next time I need the same component. I think I would need to make an iteration with conditionals.
This is what I'd like to accomplish:
SKU
Component
unicompo
SKU to produce
Component stock
Component stock after producing
20611
286
1
50
2021
1971
20611
329
1
50
2759
2709
20611
ARTZD031
1
50
643
593
220178
ARTZD027
1
384
477
93
220178
SICBB005
1
384
845
461
220178
265
1
384
894
510
220185
265
1
200
894
439
220185
SICBB005
1
200
845
390
220185
ARTZD028
1
200
71
0
220192
ARTZD029
1
200
364
164
220192
SICBB005
1
200
845
190
220192
265
1
200
894
239
I've been reading some articles and I feel like it might be done with a recursive CTE, but I don't really know how since I didn't find any example similar to mine.
How can achieve this? Any help will be appreciated. Thank you very much
I would like to add for a given product_id a price range, in 500 increments. For example a product with the price of 450 should have the price range of 500 and a product with a price 2450 should have the price range of 2000.
Main table
product_id price
32828 2593
23224 456
34344 1000
58283 2420
43585 550
Output table
product_id price price_range
32828 2593 3000
23224 456 500
34344 1000 1000
58283 2420 2000
43585 550 600
you could use case when for manage the range as you prefer
select case when price between 0 and 500 then 500
when price between 501 and 600 then 600
when price between 601 and 1500 then 1000
when price between 1501 and 2500 then 2000
END range
I am trying to create a stock holding based on the below data.
Input and Desired Output
I have tried using creating a transactions column (Starting + UK Open POs - UK Sales).
Then used the below SQL code to create a stock holding.
Sum OVER ( TRANSACTIONS)
[ <PARTITION BY No_ ]
[ <ORDER BY Date ]
But the problem is I don't want the stock holding to go into a negative. I want it to show 0, so when 960 units come in on 14/04/19 the stock holding is 921 units (960-39) instead of 116 units.
The column highlighted in yellow is my desired output. I need this over 5k SKUs (column no_)
Any help would be very appreciated.
No_ Date UK-Open PO UK-Sales Starting Stock Trans. Cumul Stock Stock Level
111111 22/03/2019 47 100 53 53 53
111111 24/03/2019 330 -330 -277 0
111111 31/03/2019 443 -443 -720 0
111111 07/04/2019 85 -85 -805 0
111111 14/04/2019 960 39 921 116 921
111111 21/04/2019 960 112 848 964 1769
111111 28/04/2019 100 -100 864 1669
111111 05/05/2019 504 -504 360 1165
111111 12/05/2019 606 -606 -246 559
111111 19/05/2019 118 -118 -364 441
111111 26/05/2019 400 -400 -764 41
111111 02/06/2019 674 -674 -1438 0
111111 09/06/2019 338 -338 -1776 0
111111 16/06/2019 206 -206 -1982 0
111111 23/06/2019 115 -115 -2097 0
111111 30/06/2019 500 66 434 -1663 434
111111 07/07/2019 33 -33 -1696 401
Suppressing the negative numbers as you are doing requires remembering what has happened on all previous rows. Alas, this can't be done using window function.
The alternative is a recursive CTE:
with t as (
select no_, date, starting_stock, trans,
row_number() over (partition by no_ order by date) as seqnum
from <table>
),
cte as (
select no_, date, trans, seqnum,
starting_stock as stock_level
from t
where seqnum = 1
union all
select t.no_, t.date, t.trans, t.seqnum,
(case when cte.starting_stock + t.trans < 0 then 0
else cte.starting_stock + t.trans
end) as stock_level
from cte join
t
on t.seqnum = cte.seqnum + 1 and
t.no_ = cte.no_
)
select *
from cte
option (maxrecursion 0);
You only need the option if the number of rows exceeds 100 from the recursion.
I previously found the solution to my problem but unfortunately I lost files on my harddrive and I can't find the statement I managed to produce.
I have 2 tables T2REQ and T2STOCK, both have 2 columns (typeID and quantity) and my problem reside in the fact that I can have multiple occurences of SAME typeID in BOTH tables.
What I'm trying to do is SUM(QUANTITY) grouped by typeID and substract the values of T2STOCK from T2REQ but since I have multiple occurences of same typeID in both tables, the SUM I get is multiplied by the number of occurences of typeID.
Here's a sample of T2REQ (take typeID 11399 for example):
typeID quantity
---------- ----------
34 102900
35 10500
36 3220
37 840
11399 700
563 140
9848 140
11486 28
11688 700
11399 390
4393 130
9840 390
9842 390
11399 390
11483 19.5
11541 780
And this is a sample of T2STOCK table :
typeID quantity
---------- ----------
9842 1921
9848 2400
11399 1700
11475 165
11476 27
11478 28
11481 34
11483 122
11476 2
And this is where I'm at for now, I know that the SUM(t2stock.quantity) is affected (multiplied) because of the JOIN 1 = 1 but whatever I tried, I'm not doing it in the right order:
SELECT
t2req.typeID, sum(t2req.quantity), sum(t2stock.quantity),
sum(t2req.quantity) - sum(t2stock.quantity) as diff
FROM t2req JOIN t2stock ON t2req.typeID = t2stock.typeID
GROUP BY t2req.typeID
ORDER BY diff DESC;
typeID sum(t2req.quantity) sum(t2stock.quantity) diff
---------- ------------------- --------------------- ----------
563 140 30 110
11541 780 780 0
11486 28 40 -12
11483 19.5 122 -102.5
9840 390 1000 -610
40 260 940 -680
9842 390 1921 -1531
9848 140 2400 -2260
11399 1480 5100 -3620
39 650 7650 -7000
37 1230 116336 -115106
36 28570 967098 -938528
35 33770 2477820 -2444050
34 102900 2798355 -2695455
You can see that SUM(t2req) for typeID 11399 is correct : 1480
And you can see that the SUM(t2stock) for typeID 11399 is not correct : 5100 instead of 1700 (which is 5100 divided by 3, the number of occurences in t2req)
What would be the best way to avoid multiplications because of multiple typeIDs (in both tables) with the JOIN for my sum substract ?
Sorry for the wall of text, just trying to explain as best as I can since english is not my mother tongue.
Thanks a lot for your help.
You can aggregate before join:
SELECT
t2req.typeID,
t2req.quantity,
t2stock.quantity,
t2req.quantity - t2stock.quantity as diff
FROM
(SELECT TypeID, SUM(Quantity) Quantity FROM t2req GROUP BY TypeID) t2req JOIN
(SELECT TypeID, SUM(Quantity) Quantity FROM t2stock GROUP BY TypeID) t2stock
ON t2req.typeID = t2stock.typeID
ORDER BY diff DESC;
Fiddle sample: http://sqlfiddle.com/#!7/06711/5
You can't do this in a single aggregation:
SELECT
COALESCE(r.typeID, s.typeID) AS typeID,
COALESCE(r.quantity, 0) AS req_quantity,
COALESCE(s.quantity, 0) AS stock_quantity,
COALESCE(r.quantity, 0) - COALESCE(s.quantity, 0) AS diff
FROM (
SELECT rr.typeID, SUM(rr.quantity) AS quantity
FROM t2req rr
GROUP BY rr.typeID
) r
CROSS JOIN (
SELECT ss.typeID, SUM(ss.quantity) AS quantity
FROM t2stock ss
GROUP BY ss.typeID
) s ON r.typeID = s.typeID
ORDER BY 4 DESC;