SQL query to sum separate columns with separate Where conditions - sql

SQL noob here. I want to sum two columns separately, using 2 separate where conditions.
ID NAME VALUE1 VALUE2
--- ------- ------- -------
1 Orange 5 30
2 Orange 11 30
3 Orange 7 15
4 Pear 12 12
5 Pear 13 25
6 Pear 4 25
Sum of VALUE1 column where values are > 10
Sum of VALUE2 column where values are > 20
Grouped by NAME
Desired output:
NAME VALUE1 VALUE2
------- ------- -------
Orange 11 60
Pear 25 50
Thanks!

Use conditional aggregation:
select name, sum(case when value1 > 10 then value1 end),
sum(case when value2 > 20 then value2 end)
from t
group by name;

I know this approach is bit tricky and lengthy as well,however this might be helpful in debugging ,if you can try this :
select
value1.name,value1.a,value2.b
from
(select sum(value1)a,name from test where value1 >10 group by name) as value1
join (select sum(value2)b,name from test where value2 >20 group by name) as value2
on value1.name = value2.name

Related

query a table with multiple rows for same id, into single data row in results

I have a few tables like this where a person has multiple data rows. The IDs are sequential but do not always start at 1. Is there a way to have the results come out in a single data row for each person. I have a few tables like this and I ultimately would like to join them via CLIENT_ID, but I'm a bit stumped. Is this possible?
Using oracle sql.
CLIENT_ID
NAME
ID
ID_DESCRIPTION
5
joe
1
apple
5
joe
5
orange
68
brian
2
orange
68
brian
6
mango
68
brian
10
lemon
12
katie
3
watermelon
where the results look like this
CLIENT_ID
NAME
ID1
ID1_DESCRIPTION
ID2
ID2_DESCRIPTION
ID3
ID3_DESCRIPTION
5
joe
1
apple
5
orange
68
brian
2
orange
6
mango
10
lemon
12
katie
3
watermelon
If Pivot ist not available, this should do it:
Select
Client_id,
sum(case when id_description='apple' then 1 else 0 end) as Apples,
sum(case when id_description='orange' then 1 else 0 end) as Oranges...
[]etc.
from
t
group by Client_ID
Might need some minor tweaking as I wrote this just off the top of my head, but something like this should work. Will say this doesn't account for more than 3 rows per CLIENT_ID. For that, would need to do a dynamic pivot (plenty of online articles on this topic).
Pivoting Based on Order of Items
WITH cte_RowNum AS (
SELECT ROW_NUMBER() OVER (PARTITION BY CLIENT_ID ORDER BY ID) AS RowNum
,*
FROM YourTable
)
SELECT CLIENT_ID
,MAX(CASE WHEN RowNum = 1 THEN ID END) AS ID1
,MAX(CASE WHEN RowNum = 1 THEN [Description] END) AS ID1_DESCRIPTION
,MAX(CASE WHEN RowNum = 2 THEN ID END) AS ID2
,MAX(CASE WHEN RowNum = 2 THEN [Description] END) AS ID2_DESCRIPTION
,MAX(CASE WHEN RowNum = 3 THEN ID END) AS ID3
,MAX(CASE WHEN RowNum = 3 THEN [Description] END) AS ID3_DESCRIPTION
FROM cte_RowNum
GROUP BY CLIENT_ID;

Select from same column but multiples values and number of records with one specific value

ID Customer Status
1 ABC 1
2 ABC 2
3 ABC 3
4 ABC 1
5 PQR 1
6 PQR 2
7 PQR 3
8 XYZ 1
9 XYZ 3
I want to select customer who has both values "status=1" and "Status=2' and also total number of entry of same customer with Status=1.
So the result will be,
Customer totalEntryStatus1
ABC 2
PQR 1
How can I do this.
Thankyou !
select Customer, count(case when status = 1 then 1 end) totalEntryStatus1
from table
where Status in (1,2)
group by Customer
having count(distinct Status) = 2

Working out the percentage of outcomes in a column within a table

I am using SQL developer and have a table called table1 which looks like this (but with loads more data):
item_id seller_id warranty postage_class
------- --------- -------- -------------
14 2 1 2
17 6 1 1
14 2 1 1
14 2 1 2
14 2 1 1
14 2 1 2
I want to identify the percentage of items sent by first class.
If anyone could help me out that would be amazing!
You can use conditional aggregation. The simplest method is probably:
select avg(case when postage_class = 1 then 1.0 else 0 end)
from t;
Note this calculates a ratio between 0 and 1. If you want a "percentage" between 0 and 100, then use 100.0 instead of 1.0.
Some databases make it possible to shorten this even further. For instance, in Postgres, you can do:
select avg( (postage_class = 1)::int )
from t;

Complicated pivot in MS SQL Server

I have the following data structure, where value1 and value2 - some aggregated values for each segment and date(I can get unaggregated data, if it helps)
date segment value1 value2
--- ------ ------- ------
What do I need is a report,which looks like this:
2015-01-01 2015-01-02
value1 value2 value1 value2
------ ------ ------ ------
segment1 19 5 18 7
segment2 20 5 21 7
for each date in a given period at the same time. How can I do that?
If I understand the question, you want the segment followed by a sum of the columns Value 1 and value 2, if So here is an easy group to do that:
select segment
, sum(Value1) as Value1
, sum(value2) as Value2
From YourTable
group by segment

SQL Converting Column into Rows in Single Select Statement

I need solution for converting SQL output
I am writing
SELECT Merchant_Master.Merchant_ID,
COUNT(Coupon_Type_ID) AS "Total Coupons",
Coupon_Type_ID,
CASE WHEN Coupon_Type_ID=1
THEN COUNT(Coupon_Type_ID)
END AS "Secret",
CASE WHEN Coupon_Type_ID=2
THEN count(Coupon_Type_ID)
END AS "Hot"
FROM Coupon_Master
INNER JOIN Merchant_Master
ON Coupon_Master.Merchant_ID=Merchant_Master.Merchant_ID
GROUP BY
Coupon_Master.Coupon_Type_ID,
Merchant_Master.Merchant_ID
and getting output as
Merchant_ID Total Coupons Coupon_Type_ID Secret Hot
----------- ------------- -------------- ----------- -----------
20 6 1 6 NULL
22 4 1 4 NULL
22 2 2 NULL 2
23 1 2 NULL 1
24 2 1 2 NULL
25 3 1 3 NULL
25 2 2 NULL 2
But I want output as
Merchant_ID Secret Hot_Coupons
----------- ------ -------------
20 6 0
22 4 2
23 0 1
24 2 0
25 3 2
Please, help me to solve the issue.
Move the CASE expressions inside the aggregates. I've also switched to using SUM rather than COUNT - there is a COUNT variant but it may display a warning about eliminating NULL values that I'd rather avoid.
SELECT Merchant_Master.Merchant_ID,
SUM(CASE WHEN Coupon_Type_ID=1
THEN 1 ELSE 0 END) AS "Secret",
SUM(CASE WHEN Coupon_Type_ID=2
THEN 1 ELSE 0 END) AS "Hot"
FROM Coupon_Master
INNER JOIN Merchant_Master
ON Coupon_Master.Merchant_ID=Merchant_Master.Merchant_ID
GROUP BY
Merchant_Master.Merchant_ID
Place it in a subquery and add group by Merchant_ID, Total, Coupons, Coupon_Type_ID
Aggregate the Secret and hot as SUM
select
...
SUM(secret) as secret,
SUM(Hot_Coupons) as Hot_Coupons
FROM (your original query) raw
group by Merchant_ID, Total, Coupons, Coupon_Type_ID