Oracle: Sum cell values for same id but different groups - oracle

I am trying to sum the values of same id but for different group (1000, 2000). Here is the table.
ID
GROUP
VALUE
101
1000
11
101
2000
10
101
5000
18
What I want as output
ID
GROUP
VALUE
101
3000
21
101
5000
18
How do I sum the VALUE column and name the Group column?
Thanks.

You need to put the groups 1000 and 2000 together like below. (Hope you don't have "GROUP" = -9999999999 in your table)
select ID, sum("GROUP")"GROUP", sum("VALUE")"VALUE"
from your_table
group by ID, case when "GROUP" in (1000, 2000) then -9999999999 else "GROUP" end
;

Related

Order column inside PIVOT on the basis of max(count_date) for each value inside in condition

I have users name in column users, I want to display all users as a column and the order of representation of column must be in descending order of their sum of data.
query:
select *
from (
select sum(tran_count) over (partition by schema) as table_name
from main_table
) pivot (sum(tran_count) for users in ('abc','lmn','pqr'));
ans:
schema table abc lmn pqr
pm sector 32 216 12
history trn 321 61 4
tap issuer 43 325 2
count: 396 602 18
so I want to represent the column abc,lmn and pqr in order of count of their data:
required answer:
schema table lmn abc pqr
pm sector 216 32 12
history trn 61 321 4
tap issuer 325 43 2
You cannot use (sub)query in pivot's in clause. What you can do is to rank users according to their summaric values and use these three values (1, 2, 3) in in. Then either use my inner query, which presents user names and sums in separate columns or make a final union, where names are listed in first row and sums in rows below as strings.
with t as (
select *
from (
select dense_rank() over (order by smu desc, users) rn,
schema_, table_, users, smt
from (
select schema_, table_, users, sum(tran_count) smt,
sum(sum(tran_count)) over (partition by users) smu
from main_table
group by schema_, table_, users))
pivot (max(users) name, max(smt) smt for rn in (1 u1, 2 u2, 3 u3)))
select null schema_, null table_, u1_name u1, u2_name u2, u3_name u3
from t where rownum = 1 union all
select schema_, table_, to_char(u1_smt), to_char(u2_smt), to_char(u3_smt)
from t
dbfiddle demo
If you really need to put user names in headers then you have to use dynamic SQL or external code-writing-code technique.
I don't know if you really have columns like table or schema, these are reserved words, also once you write tran_count and in title count_date, so I am somewhat confused. But you can see in the linked dbfiddle working example with columns schema_, table_, users, tran_count.

How to get minimum number of records for a condition in oracle

I want to get a minimum number of record based on my condition I give in where condition.
for ex: I have a table with two columns(Id, Value)
My table has data like following:
Id Value
1 001
2 001
3 001
4 002
5 002
6 003
7 004
8 004
9 004
10 004
From the above table Value '001' has 3 Ids(1,2,3) and Value '002' has 2 and so on.
Now I want to identify the Value which has minimum Ids(like in this example, it should be Value '003' with only one Id).
How to write a query for this in Oracle.?
Thanks in advance.
The query below will select the value (or values) with the lowest row count. In the case of ties, all the values with the same, smallest number of rows are selected. The row count is not shown, but it could be shown easily (add it to the outer select).
The real work is done in the aggregate subquery. In addition to the value and the count of rows, we also compute the analytic function min(count(*)) - over the entire result of the aggregation, so the analytic clause is in fact empty: over ().
select value
from (
select value, count(*) as cnt, min(count(*)) over () as min_cnt
from your_table
group by value
)
where cnt = min_cnt
You can use a GROUP BY, order by the count and finally select the first row
SELECT * FROM (
SELECT value, count(*) as cnt
FROM sometable
GROUP BY value
ORDER BY count(*)
) WHERE ROWNUM = 1
sqlfiddle: http://sqlfiddle.com/#!4/e5f075/1
If you are on Oracle 12, you can do:
select value, count(*)
from mytable
group by value
order by 2
fetch first 1 rows only
If you need to have all values that share the minimum count, then replace only with with ties.

how combine multiple rows into a single row in Oracle?

How can i do below in oracle?
input
id units unit_description
12 20 kWh
12 50 kWh
12 100 days
15 80 kWh
I want merged in column 2 and 3 based on column 1 into one single row. And the result should be like
output:
id | unit details
12 70 KWh , 100 days
15 80 KWh
Check the below query. Mostly it should work in your case. It may not execute at once, modify as per your requirement.
SELECT id,
LISTAGG (unit || ' ' || unit_description, ', ')
WITHIN GROUP (ORDER BY unit, unit_description)
FROM ( SELECT id, unit_description, SUM (unit) AS unit
FROM table1
GROUP BY id, unit_description)
GROUP BY id;

One column calculate multiple output

I have show the total product sale on the basis YTD (Year to Date), QTD(Quarter to Date) and MTD (Month to Date). The thing is I have to show only one from those. Only one output can be seen on the basis of selection i.e. like we have radio buttons to select one from many. Here also a input is given to select and on the basis of that input the output is generated. The input can be any YTD,QTD or MTD. The output is generated on the basis of input. I don't how to calculate a column output where the input can be vary.
I have a Product Table-
Product_ID Product_name Price
1 Mobile 200
2 T.V. 400
3 Mixer 300
I have a Sales table like this-
Product_ID Sales_Date Quantity
1 01-01-2015 30
2 03-01-2015 40
3 06-02-2015 10
1 22-03-2015 30
2 09-04-2015 10
3 21-05-2015 40
1 04-06-2015 40
2 29-07-2015 30
1 31-08-2015 30
3 14-09-2015 30
And my ouput column contains 3 columns that are-
Product_id, Product_Name and Total_Amount.
The column Total_Amount(quantity*price) have to calculate sale on the basis of input given by user i.e.,
IF it is YTD then it should calculate the total sale from Starting Date of Year ( 01-01-2015) to the current_date(sysdate),
IF it is QTD then in which quarter the current date is falling i.e if current month is september then from 1 July to current_date(sysdate),
IF it is MTD then in which month the current date is falling to the current_date(sysdate).
Can anyone help. Thanks!!!
-- step 1
create or replace view my_admin
as
select 'YTD' element, product_id, sum(quantity) sum_quantity
from sales
where Sales_date between trunc(sysdate,'Y') and sysdate
group by product_id
union
select 'QTD', product_id, sum(quantity) sum_quantity
from sales
where Sales_date between trunc(sysdate,'Q') and sysdate
group by product_id
union
select 'MTD', product_id, sum(quantity) sum_quantity
from sales
where Sales_date between trunc(sysdate,'MM') and sysdate
group by product_id
-- step 2
select element, p.product_name, (sum_quantity * p.PRICE) agregate
from my_admin a
inner join products p on a.product_id = p.product_id
where element = (:input)
My presumption is that you have 3 radio buttons(variables :YTD,:QTD,:MTD in my example) where just one value at a time can be picked by the user the rest will be null.
You can use a something like this to get what you want:
select SUM(a.QTY*B.PRICE) from PRODUCTS a
inner join SALES B on a.PRODUCT_ID=B.PRODUCT_ID
where
(:YTD is null or B.SALES_DATE between '01-JAN-15' and sysdate)
and
(:QTD is null or TO_CHAR(B.SALES_DATE, 'YYYY-Q')=TO_CHAR(sysdate, 'YYYY-Q'))
and
(:MTD is null or TO_CHAR(B.SALES_DATE, 'MM')=TO_CHAR(sysdate, 'MM'));
You can test it here sqlfiddle

hierarchy level in relationship table in oracle

I have a table employee which has hierarchy data of manager and employee.
Sample data.
empId ManId
101 100
102 100
1010 101
1011 101
10101 1010
I need to find the level but it is not giving me correct output. I need an output like
level Emp ID Man Id
1 101 100
1 102 100
2 1010 101
2 1011 101
3 10101 1010
Irrespective of the input as Emp ID or Man ID, the output should be constant. I am only getting the output when I am using manager id as 100 but it doesnt work when i pass value as 10101
select distinct
level,
manager_id,
employee_id
from employees
START WITH manager_id = 100
connect by manager_id= prior employee_id
order by level
START WITH clause is used to specify a root row for the hierarchy which is employee id with 101 value
Kindly use the below
select distinct
level,
manager_id,
employee_id
from employees
where level<=3
START WITH employee_id = 101
connect by manager_id= prior employee_id
order siblings by employee_id
Update1:-:-You can remove START WITH if root row is not specific
select distinct
level,
manager_id,
employee_id
from employees
where level<=3
connect by manager_id= prior employee_id
order siblings by employee_id
Check this link for more information
Hierarchical Queries

Resources