Can anyone help me with the below?
I'm trying to group by the (PO) and by (line) to get the Max of (Quantity) regardless of the value in (type).
I tried to group by PO and line both and it didn't work and showing this
error: "not group by function".
the data look like:
po
line
type
quantity
100
1
4
23
100
1
5
20
100
2
1
40
200
1
1
10
200
2
2
15
and I would like to get the below result:
po
line
type
quantity
100
1
4
23
100
2
1
40
200
1
1
10
200
2
2
15
the code:
select
orno "PO NUMBER",
pono "Line",
oltp "Line Type",
max(qoor) "Quantity"
from
table
group by orno;
One method is a correlated subquery:
select t.*
from t
where t.quantity = (select max(t2.quantity)
from t t2
where t2.po = t.po and t2.line = t.line
);
In Oracle, another option is aggregation:
select po, line,
max(type) keep (dense_rank first order by quantity desc) as type,
max(quantity) as quantity
from t
group by po, line;
The keep syntax is Oracle's fancy way of implementing a "first" aggregation function.
Related
How can i get first row of each group with all attributes without using window functions like row_number etc.
Example Data is:
id amount
1 100
1 200
2 150
2 300
2 250
3 400
What I want as a result:
id amount
1 200
2 300
3 400
No need for a window function:
SELECT id, MAX( amount ) AS amount
FROM your_table
GROUP BY id
I have a list of transactions where the ID's are repeated and I have the quantity of items being bought. I need to count the number of times that a particular number of items were purchased at once.
Row
ItmNBR
TQTY
1
123
5
2
123
5
3
123
5
3
456
25
4
456
19
I need to produce an out put like this...
ItmNBR
QTY
Occurance
123
5
3
123
19
1
123
25
1
I can get the first two columns of my result but when I attempt to counting over a partition I end up counting getting repeating numbers since I'm only looking up 9 items I just count the number of rows in which the Cnt is the same.
TOT_IVO_ITM_QTY
Count(*) OVER (PARTITION BY QTY) AS CNT
FROM dataset
WHERE YEAR(bus_dt) = 2021
AND ITM_NBR IN (12639,12940,12949,12955,13485,13666,43950,631343,1103731)
AND QTY BETWEEN 5 AND 25
ORDER BY ITM_NBR
,QTY
GROUP BY ITM_NBR, TOT_IVO_ITM_QTY```
I think you just want group by:
select ItmNBR, QTY, count(*)
from t
group by ItmNBR, QTY
order by count(*) desc;
This assumes that you want the count by item and quantity, which seems to be the gist of the question.
I have a pole table that can have one to four streetlights on it. Each row has a pole ID and the type (a description) of streetlight. I need the ID's to be unique with a column for each of the possible streetlights. The type/description can anyone of 26 strings.
I have something like this:
ID Description
----------------
1 S 400
1 M 200
1 HPS 1000
1 S 400
2 M 400
2 S 250
3 S 300
What I need:
ID Description_1 Description_2 Description_3 Description_4
------------------------------------------------------------------
1 S 400 M 200 HPS 1000 S 400
2 M 400 S 250
3 S 300
The order the descriptions get populated in the description columns is not important, e.g. for ID = 1 the HPS 1000 value could be in description column 1, 2, 3, or 4. So, long as all values are present.
I tried to pivot it but I don't think that is the right tool.
select * from table t
pivot (
max(Description) for ID in (1, 2, 3))
Because there are ~3000 IDs I would end up with a table that is ~3001 rows wide...
I also looked at this Oracle SQL Cross Tab Query But it is not quite the same situation.
What is the right way to solve this problem?
You can use row_number() and conditional aggregation:
select
id,
max(case when rn = 1 then description end) description_1,
max(case when rn = 2 then description end) description_2,
max(case when rn = 3 then description end) description_3,
max(case when rn = 4 then description end) description_4
from (
select t.*, row_number() over(partition by id order by description) rn
from mytable t
) t
group by id
This handles up to 4 descriptions per id. To handle more, you can just expand the select clause with more conditional max()s.
Hi I have the following table
Cash_table
ID Cash Rates
1 50 3
2 100 4
3 70 10
3 60 10
4 13 7
5 20 8
5 10 10
6 10 5
What I want as a result is to cumulate all the entries that have a Count(id)>1 like this:
ID New_Cash New_Rates
1 50 3
2 100 4
3 (70+60)/(10+10) 10+10
4 13 7
5 (20+10)/(8+10) 8+10
6 10 5
So I only want to change the rows where Count(id)>1 and leave the rest like it was.
For the rows with count(id)>1 I want to sum up the rates and take the sum of the cash and divide it by the sum of the rates. The Rates alone aren't a problem since I can sum them up and group by id and get the desired result.
The problem is with the cash column:
I am trying to do it with a case statement but it isn't working:
select id, sum(rates) as new_rates, case
when count(id)>1 then sum(cash)/nullif(sum(rates),0))
else cash
end as new_cash
from Cash_table
group by id
You only need group by id and aggregate:
select
id,
sum(cash) / (case count(*) when 1 then 1 else sum(rates) end) as new_cash,
sum(rates) as new_rates
from Cash_table
group by id
order by id
See the demo.
You can aggregate rate and cash columns by sum() function with grouping by id
select
id,
sum(cash)/decode( sum( nvl(rates,0) ), 0 ,1, sum( nvl(rates,0) )) as new_cash,
sum(rates) as new_rates
from cash_table
group by id
there's no nullif() function in Oracle, use nvl() instead
switch case part ( where decode() function is used ) against the
possibility of division by zero
I have tables as follow:
A deliveries
delveryid clientid deliverydate
1 10 2015-01-01
2 10 2015-02-02
3 11 2015-04-08
B items in deliveris
itemid deliveryid qty status
70 1 5 1
70 1 8 2
70 2 10 1
72 1 12 1
70 3 100 1
I need to add a column to my query that gives me the qty of each part in other deliveris of the same client.
meaning that for given data of client 10 and delivery id 1 I need to show:
itemid qty status qtyOther
70 5 1 10 //itemid 70 exists in delivery 2
70 8 2 10 //itemid 70 exists in delivery 2
72 12 1 0 //itemid 72 doesn't exists in other delivery of client 11
Since I need to add qtyOther to my existing qry i'm trying to avoid using Group By as it's a huge query and if I use SUM in select I will have to group by all items in select.
This is what I have so far:
Select ....., coalesce( SUM(a.qty) OVER (PARTITION BY a.itemid) ,0) AS qtyOther
FROM B b
LEFT JOIN A a USING
LEFT JOIN (other tables)
WHERE clientid=10 ....
This query gives me the total sum of qty per itemid for specific clientid, regardless of which delivery it is. How do I change it so it will consider the delivryid? I need something like:
coalesce( SUM(a.qty) OVER (PARTITION BY a.itemid) FROM B where deliveryid<>b.deliveryid ,0) AS qtyOther
Any suggestions how to do that?
Note: I can NOT change the condition in WHERE.
I think you just want to subtract out the total for the current delivery:
Select .....,
(coalesce( SUM(a.qty) OVER (PARTITION BY a.itemid), 0) -
coalesce( SUM(a.qty) OVER (PARTITION BY a.itemid, a.deliveryid), 0)
) as qtyOther