MYSQL sum of a field depending on the value of other field - mysql

I am trying to create a field as
1.sum the purchases field where value of purchases type=vat as purchases_vat
2.sum the purchase field where value of purchase type=exempt as purchases_exempt
source table & result table example in attached image
example table

How about this?
SUM(CASE WHEN purchases_type='vat' THEN Purchases ELSE 0 END) AS purchases_vat,
SUM(CASE WHEN purchases_type='exempt' THEN Purchases ELSE 0 END) AS purchases_exempt,

Two row version:
SELECT 'vat', SUM(purchases)
FROM source_table
WHERE purchase_type = 'vat4'
UNION
SELECT 'exempt', SUM(purchases)
FROM source_table
WHERE purchase_type = 'exempt';
One row:
SELECT
(SELECT sum(purchases) from source_table where purchase_type = 'vat4') purchase_vat,
(SELECT sum(purchases) from source_table where purchase_type = 'exempt') purchase_exempt;

This will give you the sum of purchases for 'vat'. You can similarly do this for 'exempt'
SELECT `s` FROM (SELECT SUM(purchases), type FROM my_table GROUP BY type) as T1 WHERE T1.type = 'vat

select
sum(case when purchase_type = 'vat4' then purchases else 0 end) as purchase_vat4,
sum(case when purchase_type = 'exempt' then purchases else 0 end) as purchase_exempt
from source_table

Related

How to generate the following statistic from a table?

I have a table named incident_summary that structure and data as following:
month,system_id,s_count
202104,1,50
202104,2,6
202105,1,14
202105,2,4
202106,1,1
202106,2,1
I would like to generate the following statistic:
s_count_on_202106,s_count_before_202106
2,74
where
s_count_on_202106 is sum of s_count value on 202106
s_count_before_202106 is sum of s_count value before 202106
I have tried the following SQL:
select
sum(case when month<202106 then s_count else 0 end)
sum(case when month=202106 then s_count else 0 end)
from incident_summary
group by month
However, it does not work, would you help to me to solve the problem?
Try the following Query.
May be it helps you.
SELECT
t1.s_count_on_202106,
t2.s_count_before_202106
FROM
(
SELECT
sum(s_count) AS s_count_on_202106
FROM
incident_summary
WHERE
month = 202106
) AS t1,
(
SELECT
sum(s_count) AS s_count_before_202106
FROM
incident_summary
WHERE
month < 202106
) AS t2
Sum again on your result set.
SELECT SUM(s_count_before_202106)s_count_before_202106, SUM(s_count_on_202106)s_count_on_202106
FROM
(
select
sum(case when month<202106 then s_count else 0 end)s_count_before_202106 ,
sum(case when month=202106 then s_count else 0 end)s_count_on_202106
from incident_summary
group by month
)T;

Count different values in a column, while doing total and group by different column values

We have a table with data from different nodes and one of the column will have status report as "compliant or non-compliant", sample data as below
I want to filter the table in such a way that if any of the checks on a node shows non compliant, it should be flagged as non-compliant and rest as compliant. Using below query i am able to do it
SELECT COUNT(*) AS total_nodes,
SUM(fully_compliant = 0) AS Non_compliant_nodes,
SUM(fully_compliant = 1) AS compliant_nodes
FROM (
SELECT Node, CASE WHEN SUM(Status = 'Compliant') = COUNT(*) THEN 1 ELSE 0 END AS fully_compliant
FROM your_table GROUP BY Node
)
Now, i want to group and split the result by dept as below, how can i achieve this
I think you're looking for this:
select dept,
count(*) as total_nodes,
sum(case when non_compliant_chk = 0 then 1 else 0 end) as compliant_nodes,
sum(case when non_compliant_chk > 0 then 1 else 0 end) as non_compliant_nodes
from (
select dept,
node,
sum(case when 'Non-Compliant' then 1 else 0 end) as non_compliant_chk
from your_table
group by dept,
node
) v
group by dept;
With few modifications to what Brian suggested, I am able to get the desired result
select dept,
count(*) as total_nodes,
sum(case when non_compliant_chk = 0 then 1 else 0 end) as compliant_nodes,
sum(case when non_compliant_chk > 0 then 1 else 0 end) as non_compliant_nodes
from (
select dept,
node,
COUNT(CASE WHEN Compliance-Status = 'Non-Compliant' THEN 1 END) 'non_compliant_chk'
from table WHERE DOR >= DATE(NOW()) - INTERVAL 7 DAY
group by Dept,
Node
) v
group by Dept;

SQL: Statement only returns subtotal of the first row

I have Sample Data like below:
and i use the below SQL statement :
select a.product_category_id, b.Favorite, c.In_Cart,d.Pre_sales_order,
sum(b.Favorite)+sum(c.In_Cart)+sum(d.Pre_sales_order) as SubTotal
from
(select distinct product_category_id
from item_activity
where last_item_status_code in (6,7,8)
) a
left join
(select product_category_id, count(last_item_status_code) as Favorite
from .item_activity
where last_item_status_code='6'
group by product_category_id
) b on a.product_category_id=b.product_category_id
left join
(select product_category_id, count(product_category_id) as In_Cart
from item_activity
where last_item_status_code='7'
group by product_category_id
) c on c.product_category_id=a.product_category_id
left join
(select product_category_id, count(product_category_id) as Pre_sales_order
from item_activity
where last_item_status_code='8'
group by product_category_id
) d on d.product_category_id=a.product_category_id
group by a.product_category_id
;
and achieved this:
But it just give me the subtotal of the first row....
Try this:
select product_category_id,
sum(case when last_item_status_code=6 then 1 else 0 end) As Favorite,
sum(case when last_item_status_code=7 then 1 else 0 end) As In_Cart,
sum(case when last_item_status_code=8 then 1 else 0 end) As Pre_sales_order,
count(last_item_status_code) as SubTotal
from item_activity
where last_item_status_code in (6,7,8)
group by product_category_id;
the product_category_id doesn't exist in other tables. So the Subtotal is resulting to NULL.
SUM(1 + NULL) == NULL. You can use IF or COALESCE to convert NULL to 0.

Count different rows from one table

I have table t1:
id|id_title|action
The data in table:
1|1|like
2|1|like
3|1|unlike
4|2|share
5|2|share
So I want to get next result from query:
id|count like|count unlike|count share
1|2|1|0
2|0|0|2
I try to use next query:
SELECT id_title, ( Select Count(id) From T1 WHERE action='like') As CountOfItems FROM T1 GROUP BY id_title
But it return count of first row always. What I must do? Or maybe I must changed structure of table?
Just use conditional aggregation.
select
id_title
,sum(case when action='like' then 1 else 0 end) As Count_Like
,sum(case when action='unlike' then 1 else 0 end) As Count_Unlike
,sum(case when action='share' then 1 else 0 end) As Count_Share
FROM T1
GROUP BY id_title
SELECT id_title AS id, SUM(action='like') AS 'count like',
SUM(action='unlike') AS 'count unlike', SUM(action='share')
AS 'count share' FROM t1 GROUP BY id_title
Let me know if that worked for you.

How to combine two count queries to their ratio?

I have two queries:
select count(*) from my_table where status="accepted"
and
select count(*) from my_table where status="rejected"
I was to find the ratio of accepted/reject so I Was wondering if it's possible to combine the two queries so I don't have to execute two queries
Putting this answer since none offered so far is correct
select count(case when status = "accepted" then 1 end) /
count(case when status = "rejected" then 1 end) as Ratio
from my_table
where status in ("accepted","rejected")
If you also need the individual counts
select count(case when status = "accepted" then 1 end) Accepted,
count(case when status = "rejected" then 1 end) Rejected,
count(case when status = "accepted" then 1 end) /
count(case when status = "rejected" then 1 end) as Ratio
from my_table
where status in ("accepted","rejected")
Note: MySQL does not have a divide by zero problem. It returns NULL when Rejected is 0.
select accepted_count, rejected_count, accepted_count/rejected_count ratio
from (
select sum(CASE WHEN status="accepted" THEN 1 ELSE 0 END) accepted_count,
sum(CASE WHEN status="rejected" THEN 1 ELSE 0 END) rejected_count
from my_table
) A
I think this will work:
SELECT (Select count(*) from my_table where status="accepted") / (select count(*) from my_table where status="rejected") AS ratio
select status, count(*) from my_table
where status in ("rejected", "accepted")
group by status;
select sum(case when status='accepted' then 1 else 0 end) as AcceptedCount,
sum(case when status='rejected' then 1 else 0 end) as RejectedCount
from my_table