I need help..
I have table orders like this
id,order_date,price,customer_id
1 01.01.2001 100 1
2 01.02.2001 0 1
3 20.02.2001 0 1
4 04.04.2001 200 1
I need select result like this
id,order_date,price,customer_id,somefield
1 01.01.2001 100 1 100
2 01.02.2001 0 1 100
3 20.02.2001 0 1 100
3 04.04.2001 200 1 200
Try sql like this
select a.id,order_date,
coalesce(a.price,0) price,
customer_id
sum(coalesce(a.price,0)) OVER (order by a.order_date) somefield,
from tb_orders a
where a.customer_id=4583 and a.orderstate = 1
order by a.order_date
but result gives this
id,order_date,price,customer_id,somefield
1 01.01.2001 100 1 100
2 01.02.2001 0 1 100
3 20.02.2001 0 1 100
3 04.04.2001 200 1 300
You could create subgroup:
SELECT *, MAX(price) OVER(PARTITION BY grp) AS somefield
FROM (
select a.id,order_date,
coalesce(a.price,0) price,
customer_id,
sum(CASE WHEN price = 0 THEN 0 ELSE 1 END) OVER (order by a.order_date) grp
from tb_orders a
where a.customer_id=4583
and a.orderstate = 1
) sub
order by order_date;
db<>fiddle demo
Related
I m having data in columns as:
item_id
month_in
amount
1
1
1500
1
1
1000
2
1
2500
3
1
2600
3
1
1000
4
1
2700
4
1
1000
1
2
1500
1
2
2000
2
2
1000
3
3
2500
3
3
2500
4
3
1000
4
3
2500
I want to have like this result
item_id
januari
februari
maret
1
2500
3500
0
2
2500
1000
0
3
3600
0
0
4
3700
0
3500
in oracle sql query how to solve this.
please help me
I have try this
select
item_id,
(case month_in=1 then sum(amout) end) AS januari
from table
group by item_id, month_in
order by item_id asc
but not working as I expected
We can try a pivot query here:
SELECT
item_id,
SUM(CASE WHEN month_in = 1 THEN amount ELSE 0 END) AS januari,
SUM(CASE WHEN month_in = 2 THEN amount ELSE 0 END) AS februari,
SUM(CASE WHEN month_in = 3 THEN amount ELSE 0 END) AS maret
FROM yourTable
GROUP BY
item_id
ORDER BY
item_id;
You almost got it. This is the simplest solution, without extra hassle:
SELECT
item_id,
SUM(CASE WHEN month_in = 1 THEN amount ELSE 0 END) AS januari,
SUM(CASE WHEN month_in = 2 THEN amount ELSE 0 END) AS februari,
SUM(CASE WHEN month_in = 3 THEN amount ELSE 0 END) AS maret
from table
group by item_id
order by item_id asc
You don't need to define the months as a separate rowset, because the months are defined as values 1, 2, 3, ... as columns. Similarly, the items are defined by the group by function.
This is the table t. I want to group it every time the TotalQty >= 5n (let n = group). i.e. once the TotalQty >= 5n I want to sum together the qty from n-1 to n.
ID DateCreated CurrQty
1 01-20-2020 1
2 01-21-2020 4
3 01-22-2020 3
4 01-23-2020 3
5 01-25-2020 1
6 02-13-2020 3
7 02-16-2020 2
With this query I can get pretty close but I doesn't consider the the previous "valid" TotalQty + 5
select DateCreated, CurrQty, TotalQty
, ceiling(TotalQty/5.0) GroupNum
from
(
select DateCreated, CurrQty
, SUM(CurrQty) OVER (ORDER BY DateCreated ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) TotalQty
from t
) t2
ID DateCreated CurrQty TotalQty GroupNum
1 01-20-2020 1 1 1
2 01-21-2020 4 5 1
3 01-22-2020 3 8 2
4 01-23-2020 3 11 3
5 01-25-2020 1 12 3
6 02-13-2020 3 15 3
7 02-16-2020 2 17 4
---
How do I get this result?
ID DateCreated CurrQty TotalQty GroupNum
1 01-20-2020 1 1 1
2 01-21-2020 4 5 1
3 01-22-2020 3 8 2
4 01-23-2020 3 11 2 (from ID2, 11 >= (5+5))
5 01-25-2020 1 12 3
6 02-13-2020 3 15 3
7 02-16-2020 2 17 3 (from ID4, 17 >= (11+5))
And so on, the next group would be until 17+5 = 22
You need to use a recursive CTE for this:
with cte as (
select id, datecreated, currqty, currqty as totalqty, 1 as groupnum
from t
where id = 1
union all
select t.id, t.datecreated, t.currqty,
(case when cte.totalqty >= 5 then t.currqty else t.currqty + cte.totalqty end),
(case when cte.totalqty >= 5 then groupnum + 1 else groupnum end)
from cte join
t
on t.id = cte.id + 1
)
select *
from cte;
EDIT:
Hold on. I think the answer is simpler.
select t.*,
1 + ceil((totalqty - qty + 1) / 5.0)
from (select t.*,
sum(qty) over (order by date) as totalqty
from t
) t;
How to add an increment value (not summarize) with some condition on another column?
I'm using Oracle-like DBMS, named Tibero, for simple example i want to produce this data
ROWNUM GRP_STRT GRP_NO SLBY
1 1 1 1
2 1 1 1
3 1 1 1
4 1 1 1
5 1 1 1
6 1 2 0
7 1 2 0
8 1 3 1
9 1 3 1
10 1 3 1
11 1 4 0
12 1 5 1
Column SLBY is for Buy/Sell code (0=Buy, 1=Sell) then every changing type of transaction, column GRP_NO increasing (but it's not grouping by SLBY column)
SELECT CASE
WHEN ROWNUM = 1 THEN GRP_NO
WHEN ROWNUM <> 1 AND SLBY = LAG(SLBY,1) over (ORDER BY ROWNUM) THEN LAG(GRP_STRT,1) over (ORDER BY ROWNUM) - 1
WHEN ROWNUM <> 1 AND SLBY_DSTN_CD <> LAG(SLBY_DSTN_CD,1) over (ORDER BY ROWNUM) THEN LAG(GRP_STRT,1) over (ORDER BY ROWNUM) + 1
END TARGET_GROUPING
, A.*
FROM SOME_TABLE
I tried with that query but instead of getting what i want like in the picture above, I produced a GRP_NO like 1 1 1 1 1 2 1 1 1 1 2 1 1 1 (first change SLBY only)
Apologies for my bad english and bad explanation, I'll explain more if need further information, thanks for your help!
As far as I understood your problem,
You are trying to calculate GRP_NO from ROWNUM, GRP_STRT, GRP_NO, and SLBY.
I have created the following query for you.
You can check the logic and apply it in your code accordingly:
SELECT
RN,
GRP_STRT,
SUM(CASE
WHEN PREV_SLBY_DSTN_CD IS NULL
OR PREV_SLBY_DSTN_CD <> SLBY_DSTN_CD THEN 1
END) OVER(
ORDER BY
RN
) AS GRP_NO,
SLBY_DSTN_CD AS SLBY
FROM
(
SELECT
RN,
LAG(SLBY_DSTN_CD) OVER(
ORDER BY
RN
) AS PREV_SLBY_DSTN_CD,
SLBY_DSTN_CD,
GRP_STRT
FROM
(SELECT ROWNUM RN, .... FROM SOME_TABLE) A
)
This code is to generate the output as shown in question:
ROWNUM GRP_STRT GRP_NO SLBY
1 1 1 1
2 1 1 1
3 1 1 1
4 1 1 1
5 1 1 1
6 1 2 0
7 1 2 0
8 1 3 1
9 1 3 1
10 1 3 1
11 1 4 0
12 1 5 1
Cheers!!
am trying to do this query. This is what I have.
My table is: Table
QId InternalId type. priority userid
100 100 1 0 X101
100 100 1 1 X102
100 100 2 0 X103
100 100 2 0 X104
100 100 2 0 X105
100 100 3 0 X106
100 100 3 0 X107
101 101 2 1 X114
101 101 2 0 X115
101 101 3 0 X116
101 101 3 0 X117
For QId and InternalId we have type 1,2,3. I need 1 row for each group based type. Here condition is if priority is 1 then we need take that record. if priority is not set need to take first record.
I need result like below table
QId InternalId type. priority userid
100 100 1 1 X102
100 100 2 0 X103
100 100 3 0 x106
101 101 2 1 X114
101 101 3 0 X116
Can you please help me out in this
Just use row_number():
select t.*
from (select t.*,
row_number() over (partition by QId, InternalId, type order by (select null)) as seqnum
from t
) t
where seqnum = 1;
You can try using row_number()
select * from
(
select *, row_number() over(partition by qid, internalid, type order by priority desc) as rn
from tablename
)A where rn=1
use row_number() window function
select t.* from (select *,row_number()over(partition by QId,InternalId,type order by case when priority=1 then 1 else 2 end) rn
) where t.rn=1
Another approach can be WITH TIES like following.
select top 1 with ties *
from #table
order by row_number() over (partition by QId, InternalId, type order by (select 1))
Online Demo
I have the following Result from Select statement
UnitId UnitType GroupId
1 1 1
2 1 1
3 1 2
4 2 2
5 2 2
6 2 2
7 2 2
I need the following result for each group Id
GroupId CountBasedOnUnitType1 CountBasedOnUnitType2
1 2 0
2 1 4
Thanks in advance.
Try this
SELECT * FROM
(
SELECT GroupId,
UnitType
FROM Table1
) x
Pivot
(
Count(UnitType)
For UnitType in ([1], [2])
) p
Fiddle Demo
Output
GroupId 1 2
1 2 0
2 1 4
Does in necessarily need to have OVER?
select
GroupID,
sum(case when UnitType = 1 then 1 else 0 end) CountBasedOnUnitType1,
sum(case when UnitType = 2 then 1 else 0 end) CountBasedOnUnitType2
from table
group by GroupID