Need resultset on following resultset in SQL - sql

I have result set as follows:
Employer_id Type Amount
1 penalty 100
1 interest 120
2 penalty 50
2 interest 60
2 contribution 70
1 contribution 140
I need result as:
Employer_id penalty interest contribution**
1 100 120 140
2 50 60 70
How can I do this in SQL?

Please take a moment and learn how to format your questions.
A simple conditional aggregation should do the trick
Select Employer_id
,penalty = sum(case when [type]='penalty' then amount else 0 end)
,interest = sum(case when [type]='interest' then amount else 0 end)
,contribution = sum(case when [type]='contribution' then amount else 0 end)
From YourTable
Group By Employer_id

Related

Find the percentage for both cash and credit

So, I have a column 'Type' that has cash and credit transactions. I want to find the percentage for both as results. Can anybody help me accomplish this?
SELECT COUNT(Type),
SUM(CASE WHEN Type = 'Cash' THEN 1 ELSE 0 END)/COUNT(*) * 100 AS PercentageCashTransaction,
SUM(CASE WHEN Type = 'Credit' THEN 1 ELSE 0 END)/COUNT(*) * 100 AS PercentageCreditTransaction
FROM vending_machine_sales
GROUP BY type;
Actual results:
TYPE
%Cash
%Credit
2148
0
100
4297
100
0
Desired results:
%Cash
%Credit
67%
33%

SQL: SUM OR COUNT with CASE WHEN condition in multiple criteria

Course name
Section number
Course type
MATH 101
1
In person
MATH 101
2
In person
MATH 101
3
Online
MATH 101
4
In person
SOC 101
1
In person
SOC 101
2
In person
SOC 101
3
In person
ENGL 201
1
In person
ENGL 201
2
Online
ENGL 201
3
Online
ENGL 201
4
In person
PHY 101
1
Online
PHY 101
2
Online
From this table, I'd like to count Courses with only an 'In person' course, an 'Online' course, and both course types.
The query I tried is below.
SELECT
SUM(CASE WHEN coursetype = 'Inperson' AND coursetype = 'Online' THEN 1 ELSE 0 END) AS bothtype,
SUM(CASE WHEN coursetype = 'Online' THEN 1 ELSE 0 END) AS Onlineonly,
SUM(CASE WHEN coursetype = 'Inperson' THEN 1 ELSE 0 END) AS Onlineonly
From Course
The result what I expected is
bothtpye
Onlineonly
Inpersononly
2
1
1
but I got
bothtpye
Onlineonly
Inpersononly
0
7
6
Please advise me to get through this.
Thank you.
My solution uses double conditional aggregation.
SELECT SUM (CASE WHEN In_Person > 0 AND Online > 0 THEN 1 ELSE 0 END) as bothtype,
SUM (CASE WHEN In_Person > 0 AND Online = 0 THEN 1 ELSE 0 END) as inpersononly,
SUM (CASE WHEN In_Person = 0 AND Online > 0 THEN 1 ELSE 0 END) as onlineonly
FROM (
SELECT Course_name,
SUM(CASE WHEN Course_type='In Person' THEN 1 ELSE 0 END) as In_Person,
SUM(CASE WHEN Course_type='Online' THEN 1 ELSE 0 END) as Online
FROM Course
GROUP BY Course_name
) tot
DEMO Fiddle
SUGGESTION ( using PL/SQL ! ) :
CREATE PROCEDURE countCourses(OUT bothtype INT,OUT Inpersononly INT,OUT Onlineonly INT)
begin
SELECT COUNT(*) INTO bothtype FROM Course;
select COUNT(*) INTO Inpersononly FROM Course
WHERE courseType = "In person";
select COUNT(*) INTO Onlineonly FROM Course
WHERE courseType = "Online";
end;
call countCourses(#bothtype,#Inpersononly,#Onlineonly);
SELECT #bothtype,#Inpersononly,#Onlineonly;
EXPLICATION :
Creating procedure to store the count of each type of course in OUT variable
Call the procedure with convenient parameters
Select out given parameters

SQL transform table with sum based on values

i have table like this:
operation_id
order_id
qty
qty_type
detail_type
1
1
240
ready
glued
1
1
199
ready
unglued
1
1
100
done
glued
1
2
50
ready
glued
and would like to transform into this. it means to add 4 columns and to sum them from above table based on a conditions, like detail_type = 'glued', qty_type = 'ready' etc.
operation_id
order_id
qty_glued_ready
qty_unglued_ready
qty_glued_done
qty_unglued_done
1
1
240
199
10
10
can somebody help me how query should look like?
I assume it is just an example that you have mentioned in your OP and it is not accurate according to your table data you have mentioned.
I don't understand how your qty_glued_done is 10
But here is something you can start working out with:
SELECT o.`operation_id`, o.`order_id`,
SUM(CASE WHEN `detail_type`='glued' AND o.`qty_type`='ready' THEN o.`qty` ELSE 0 END) AS qty_glued_ready,
SUM(CASE WHEN `detail_type`='unglued' AND o.`qty_type`='ready' THEN o.`qty` ELSE 0 END) AS qty_unglued_ready
(and so on)
FROM `operation_table` o GROUP BY o.`operation_id`

Transpose data in HIVE

I have the following dataset in Hive, and I would like to transpose rows into columns.
Customer
Status
Quantity
25
Paid
5
25
N Paid
2
67
Open
12
67
Paid
4
45
N Paid
3
45
Open
2
I would like to have a new table after transpose that shows only one line by a customer and multiple columns by Status, e.g.
Customer
Paid
N Paid
Open
25
5
2
0
67
4
0
12
45
0
3
2
I tried some examples I've found on the Internet, but I could not make it works. Here, for the sake of simplicity, I listed only three statuses, but in fact, I could have more than that.
In SAS, I used to did something such as the following:
proc transpose
data = imputtable;
out = outputtable;
by customer;
id status;
var quantity;
run;
SAS gets all the existing statuses and pivots them into columns. I was looking to do the same in Hive.
Regards,
Marcio
Use conditional aggregation:
select Customer,
sum(case when Status = 'Paid' then Quantity else 0 end) as Paid ,
sum(case when Status = 'N Paid' then Quantity else 0 end) as `N Paid` ,
sum(case when Status = 'Open' then Quantity else 0 end) as Open
from table
group by Customer

Summary Statistics for different categories using hive

I have below two hive tables called a and b. I need to create descriptive summary stats for it.
Now I want to calculate the summary statistics like below:
Expected output
Sum of Amount Count Sum of Fraud Amount Count of Fraud
0-100 120 2 70 1
100-500 610 3 410 2
>500 1300 2 700 1
Where I need Sum of Amount and count by categories mentioned like 0-100, 100-500 and >500.
Second i also need Sum of fraud amount (Where Fraud = 1) and count of frauds.I need to left join to get fraud column to calculate it.
e.g Category 0-100, The sum of amount is 120 (50+70) and count is 2. And Sum of fraud amount is 70 where fraud is 1. Similarly for others i need to calculate.
Table a
ID Amount Date
1 110 01-01-2020
2 200 02-01-2020
3 50 03-01-2020
4 600 04-01-2020
5 700 05-01-2020
6 70 06-01-2020
7 300 07-01-2020
Table b
ID Fraud
1 1
2 0
3 0
4 0
5 1
6 1
7 0
My Approach where i got overall count and Amount sum but i need category wise like, 0-100, 100-500, and >500
select sum(a.Amount), Count(*), count(b.Fraud)
from sample.data a
left join (select id, fraud from sample.label) b
on a.id = b.id
where date between "2020-01-01" and "2020-01-07"
group by fraud;
If I understand correctly, you just need to aggregate by a case expression:
select (case when d.amount <= 100 then '0-100'
when d.amount <= 500 then '101-500'
else '> 500'
end) as grp,
sum(d.Amount), Count(*), sum(l.Fraud)
from sample.data d left join
sample.label l
on a.id = l.id
where d.date between '2020-01-01' and '2020-01-07'
group by (case when d.amount <= 100 then '0-100'
when d.amount <= 500 then '101-500'
else '> 500'
end);