Joining two rows into one rows (different column) in oracle - sql

I have table with values like this
ID |Name |Balance |Type |ProductName
1 Abdol 10000 1 RAID100
2 HIVE 5000000 2 RAID100
3 Ade 20000 1 RAID200
4 Koi 30000 1 RAID100
I want to re-arrange the table using select script to:
ProductName | Balance_Type_1 | Balance_Type_2
RAID100 40000 5000000
RAID200 20000 0
I've tried nested case when, but it always create one column with Product-name followed by 0 value besides and repeated.
Thank You

You want aggregation :
select productname,
sum(case when type = 1 then balance else 0 end) as balance_type1,
sum(case when type = 2 then balance else 0 end) as balance_type2
from table t
group by productname;
Run the aggregation query whenever is needed, do not create summary table structure in the database. It will be difficult to manage.

One option would be using pivot provided you database has version 11g+ :
select ProductName ,
sum(nvl(Balance_Type_1,0)) as Balance_Type_1,
sum(nvl(Balance_Type_2,0)) as Balance_Type_2
from t
pivot
(
sum( Balance ) for Type in ( 1 as Balance_Type_1, 2 as Balance_Type_2 )
)
group by ProductName;
Demo

Related

Is there a way to count the number of values in column?

I am a newbie studying MSSQL and Database.
I am trying to write a SQL query to count values in the column.
Following table is original one.
name value
----------
A 1
A 1
A 2
B 1
B 2
I want to get a table like this.
name one two
--------------
A 2 1
B 1 1
A has two 1 and one 2 and B has one 1 and 2. It seems I can accomplish it using COUNT built-in function. I tried but failed. Is there any idea to do it?
use conditional aggregation
select name, sum(case when value=1 then 1 else 0 end) as one,
sum(case when value=2 then 1 else 0 end) as two
from table_name group by name

Find whether id matches and substitute using Case Hive query

I have a table called "Scan" customer transactions where an individual_id appears once for every different transaction and contains column like scan_id.
I have another table called ids which contains random individual_ids sampled from Scan Table
I would like to join ids with scan and get a single record of ids and scan_id if it matches certain values.
Suppose data is like below
Scan table
Ids scan_id
---- ------
1 100
1 111
1 1000
2 100
2 111
3 124
4 1000
4 111
Ids table
id
1
2
3
4
5
I want below output i.e if scan_id matches either 100 or 1000
Id MT
------ ------
1 1
2 1
3 0
4 1
I executed below query and got error
select MT, d.individual_id
from
(
select
CASE
when scan_id in (90069421,53971306,90068594,136739913,195308160) then 1
ELSE 0
END as MT
from scan cs join ids r
on cs.individual_id = r.individual_id
where
base_div_nbr =1
and
country_code ='US'
and
retail_channel_code=1
and visit_date between '2019-01-01' and '2019-12-31'
) as d
group by individual_id;
I would appreciate any suggestions or help with regard to this Hive query. If there is an efficient way of getting this job done. Let me know.
Use a group by:
select s.individual_id,
max(case when s.scan_id in (100, 1000) then 1 else 0 end) as mt
from scan s
group by s.individual_id;
The ids table doesn't seem to be needed for this query.

Merging multiple rows into one using Postgresql

I am trying to combine multiple rows with the same IDs to one.
My raw table looks like this:
ID | person_id | eur_amount
1 3 200
1 2 100
2 3 80
2 2 100
The output should look like this:
ID | person_1 | eur_amount_1 | person_2 | eur_amount_2 |
1 3 200 2 100
2 3 80 2 100
The max number of persons is the same. I already tried solving it with a multiple JOIN statements and the crosstab() function as mentioned here PostgreSQL Crosstab Query.
But I couldn't find a solution for this - does anyone know a good way to achive the desired output?
Thanks in advance!
You can do this using cross tab or conditional aggregation. But you need to identify the rows, using row_number(). For instance:
select id,
max(case when seqnum = 1 then person_id end) as person_id_1,
max(case when seqnum = 1 then eur_amount end) as eur_amount_1,
max(case when seqnum = 2 then person_id end) as person_id_2,
max(case when seqnum = 2 then eur_amount end) as eur_amount_2
from (select t.*,
row_number() over (partition by id order by id) as seqnum
from t
) t
group by id;

How to use the SUM function on a specific table two times and then make a deduction

Is it possible in the same SQL query to use the SUM function for different occasions;
For example, lets use the below SQL table called 'TEMPTABLE'
On the table you can see that the item with ITEM_ID=001 appears three times. On the first two times appears with the OCCASION 1 and on the last one with the OCCASION 2.
What I want to do is to make a SUM on THE QTY column that have the same ITEM_ID=001 and OCCASION=1 AND then deduct the SUM of the QTY with the OCCASION 2 and ITEM_ID=001
TEMPTABLE
ITEM_ID QTY OCCASION
--------------------
001 2 1
002 3 1
001 4 1
003 2 1
001 1 2
For the ITEM_CODE=001 the result should be (2+4)-1=5.
Is it possible to do that with one query?
SELECT ITEM_ID,
SUM(CASE WHEN OCCASION = 1 THEN QTY ELSE 0 END)
- SUM(CASE WHEN OCCASION = 2 THEN QTY ELSE 0 END)
FROM TEMPTABLE
GROUP BY ITEM_ID
Please use the below code. Its working fine in SQL Server 2012.
DECLARE #TEMPTABLE TABLE (ITEM_ID Char(5), QTY int, OCCASION int)
INSERT INTO #TEMPTABLE
(ITEM_ID,QTY,OCCASION)
VALUES
(001,2,1),
(002,3,1),
(001,4,1),
(003,2,1),
(001,1,2)
SELECT ITEM_ID,
SUM(CASE WHEN OCCASION = 1 THEN QTY ELSE 0 END)-
SUM(CASE WHEN OCCASION = 2 THEN QTY ELSE 0 END) AS Total
FROM #TEMPTABLE
GROUP BY ITEM_ID
Output:
ITEM_ID Total
1 5
2 3
3 2
select item_id, sum(qty*(3 - 2*occasion))
from table
group by item_id

SQL find total count of each type in a column

I'm learning SQL and am stumped on what should be a simple query. I have a table with the following pattern:
Id | Type
------------
1 | Red
2 | Blue
3 | Blue
4 | Red
..
I would like to write a query to return a table that counts the total number of instances of each type and returns a table with the following pattern, for example, if 'Blue' occurs in 12 rows, and 'Red' occurs in 16 rows in the table above, the result would be:
Blue | Red
-----------
12 | 16
You could do it this way:
SELECT Type, COUNT(*) FROM TABLE GROUP BY Type
If you'd like to see the Types in separate columns, you could do this:
SELECT SUM(CASE WHEN Type = 'Blue' THEN 1 ELSE 0 END) AS Blue, SUM(CASE WHEN Type = 'Red' THEN 1 ELSE 0 END) AS Red FROM TABLE
I suggest using count over partition by. Here's a code I wrote to help my company check for duplicate Technician EmployeeID's and Pincodes, including count and YES/NO columns to allow filtering in excel so they can see what corrections need to be made:
select
t.TechnicianId, t.TechnicianName, t.Pincode, t.EmployeeID
, [Pincode Count] = count(t.Pincode) over (partition by t.Pincode)
, [Duplicate Pincode?] = case count(t.Pincode) over (partition by t.Pincode) when 1 then 'NO' else 'YES' end
, [EmployeeID Count] = count(t.EmployeeID) over (partition by t.EmployeeID)
, [Duplicate EmployeeID?] = case count(t.EmployeeID) over (partition by t.EmployeeID) when 1 then 'NO' else 'YES' end
from Technicians t
group by t.TechnicianId, t.TechnicianName, t.Pincode, t.EmployeeID
order by 4