SQL: Sum of count statements containing where clause - mysql

I have 3 count statements, which I need to combine and take a sum of.
SELECT COUNT(status)
FROM tableA
WHERE env='test'
AND deploy_date='2016-10-19'
AND platform='MA'
AND server='B'
AND status='5';
SELECT COUNT(status)
FROM tableA
WHERE env='test'
AND deploy_date='2016-10-19'
AND platform='MA'
AND server='B'
AND status='3';
SELECT COUNT(status)
FROM tableA
WHERE env='test'
AND deploy_date='2016-10-19'
AND platform='MA'
AND server='B'
AND status='1';
I tried
SELECT (select count(status)
FROM tableA
WHERE env='test'
AND deploy_date='2016-10-19'
AND platform='MA'
AND server='B' and status='5'; ) +
(SELECT COUNT(status)
FROM tableA WHERE env='test'
AND deploy_date='2016-10-19'
AND platform='MA'
AND server='B' AND status='3';) +
(SELECT COUNT(status)
FROM tableA
WHERE env='test'
AND deploy_date='2016-10-19'
AND platform='MA'
AND server='B' AND status='1';)
But getting syntax error. What am I missing? Is there a better way to accomplish this in MySQL.
Thanks in advance

Here is one way to combine
SELECT count(1)
FROM tableA
WHERE env = 'test'
AND deploy_date = '2016-10-19'
AND platform = 'MA'
AND server = 'B'
AND status IN ( '5', '3', '1' );

Please try this one, it is very simple query.
SELECT status, count(status) from tableA
WHERE env='test' AND deploy_date='2016-10-19' AND platform='MA' AND server='B' AND status in ('1','3','5')
Group by status
above will return individual count and sum if you want sum of all then just remove group by clause.

SELECT count(status)
FROM tableA
WHERE env = 'test'
AND deploy_date = '2016-10-19'
AND platform = 'MA'
AND server = 'B'
AND status IN ( '5', '3', '1' );
You can combine the statement into one, status differ, rest all the filtration are same.
For status wise count, add group by clause Group By Status at the end of the SQL script.
SELECT Status,count(status)
FROM tableA
WHERE env = 'test'
AND deploy_date = '2016-10-19'
AND platform = 'MA'
AND server = 'B'
AND status IN ( '5', '3', '1' )
Group By Status

Related

Find the latest rows by filtering the status

I have a table called person_list. The data is,
Insert into person_list(person_allocation_id, person_id, created_datetime, boss_user_name, allocation_status_id) values
(111008, 1190016, '2021-01-05 11:09:25', 'Rajesh', '2'),
(111007, 1190015, '2020-12-12 09:23:31', 'Sushmita', '2'),
(111006, 1190014, '2020-12-11 10:48:26', '', '3'),
(111005, 1190014, '2020-12-10 13:46:15', 'Rangarao', '2'),
(111004, 1190014, '2020-12-10 13:36:10', '', '3');
Here person_allocation_id is the primary key.
person_id may be duplicated some times.
All of these rows are sorted by person_allocation_id (in descending order)
Now, I would like to filter the rows which are having allocation_status_id = '2' and boss_user_name should be non-empty for the person_id.
The difficulty here is that I have to exclude the row if the person_id is having allocation_status_id = '3' as their latest status (according to date).
I am unable to understand how could I compare the dates in one row with another in the previous row.
So finally I should get only 2 rows in my final result set (person_allocation_id are 111008 and 111007).
Somehow I achieved this in Oracle.
select person_id, person_allocation_id, create_datetime, boss_user_name, allocation_status_id
from (
select person_id, person_allocation_id, create_datetime, boss_user_name, allocation_status_id,
rank() over (partition by person_id order by create_datetime desc) rnk
from person_list
where allocation_status_id = '2')
where rnk = 1;
But, I need this for MySql DB. Anyone, please help?
Thanks.
SELECT t1.*
FROM person_list t1
JOIN ( SELECT MAX(t2.person_allocation_id) person_allocation_id, t2.person_id
FROM person_list t2
GROUP BY t2.person_id ) t3 USING (person_allocation_id, person_id)
WHERE t1.allocation_status_id = '2'
fiddle
Add more conditions to WHERE clause if needed (for example, AND boss_user_name != '').
You can use a correlated subquery to get the latest allocation_status_id value per person_id:
select person_allocation_id
, person_id
, created_datetime
, boss_user_name
, allocation_status_id
from (
select person_allocation_id
, person_id
, created_datetime
, boss_user_name
, allocation_status_id
, (select pl2.allocation_status_id
from person_list pl2
where pl2.person_id = pl.person_id
order by pl2.created_datetime desc
limit 1) latest_allocation_status_id
from person_list pl) t
where
allocation_status_id = '2' and latest_allocation_status_id <> '3'
and boss_user_name <> ''
The outer query is able to check the latest status and return the expected result set. The query works for MySQL 5.7
Demo here
As a side note, for MySQL 8.0 you can replace the correlated subquery with a window function:
last_value(allocation_status_id) over (partition by person_id
order by created_datetime desc)
Demo for window function

Get the student result from status when grouping in mysql

I have created a temporary table from records which looks like below. I want to group student using student id (stu_D). While grouping student result status will be PASSED if he passed all the subject and FAILED if he failed at least one.thanks in advanced
You can try below query -
SELECT stu_D
,stuName
,CASE
WHEN T2.CNT = 0
THEN 'passed'
ELSE 'failed'
END status
FROM (SELECT stu_D
,stuName
,COUNT(CASE
WHEN result = 'FAILED'
THEN 1
END) CNT
FROM T
GROUP BY stu_D
,stuname) T2
SELECT
T.stu_D, T.stuName, IF(T.number_of_failures>0, 'FAILED', 'PASSED') final_result
FROM
(SELECT
stu_D, stuName, COUNT(IF(result='FAILED', 1, NULL)) number_of_failures
FROM your_table
GROUP BY stu_D, stuName) T;
try this query
SELECT stu_Name,result
FROM `marks`
WHERE stu_D not in
(SELECT stu_D FROM marks WHERE result='FAILED')
GROUP BY stu_D

Need help DB Query for this scenario

I am unable to derive a SQL query for the following table content.
When i tried below query i am getting above said output. Can someone help me to give the required query for it.
select Name, count(Status) from mytable where Status='Open' group by mytable union
select Name, count(Status) from mytable where Status='Cleared' group by mytable
Use case expressions in the select list to do conditional aggregation.
select Name,
count(case when Status = 'Open' then 1 end) as opencnt,
count(case when Status = 'Cleared' then 1 end) as clearedcnt
from mytable
where Status in ('Open', 'Cleared')
group by Name
COUNT() counts non-null values. The case expressions above returns null when the conditions aren't fulfilled.

multiple select on stored procedure

I'm trying to do multiple selects from one table but it only shown the last select statement.
CREATE PROCEDURE `usp_GetStockCard` (IN Matecode varchar(10))
BEGIN
(select tran_date as tran_date
from TM_matbalance
where Mate_code=Matecode);
(select Mate_code as Mate_code
from TM_matbalance
where Mate_code=Matecode);
(select tran_qtyx as Qty_in
from TM_matbalance
where tran_type='IN'
and mate_code=matecode);
(select tran_qtyx as Qty_out
from TM_matbalance
where tran_type='OUT'
and mate_code=matecode);
END
I've tried to change semicolon to comma after each select statement but it said that syntax error: missing 'semicolon'.
please help.
I look at your problem and I think I solve it.
Basically there is two problems here first one is to pivot your table where your Tran_Qtyx column become Qty_In and Qty_Out based on value in Tran_Type column (IN or OUT)... That part of problem you solve with this query
SELECT Tran_Date, Mate_Code,
SUM(CASE WHEN Tran_Type = 'IN' THEN Tran_Qtyx ELSE 0 END) Qty_In,
SUM(CASE WHEN Tran_Type = 'OUT' THEN Tran_Qtyx ELSE 0 END) Qty_Out
FROM myTable
WHERE Mate_Code = 'MAT001'
GROUP BY DATE(Tran_Date)
NOTE: In your desired result I only see 'MAT001'as Mate_Code so I stick with that in this solution and exclude MAT002 from result.
More about pivot table you can read here, there you can find a link, which is good to take a look, and where you can find a lot of stuff about mysql query's.
The second part of your problem is to get Qty_Balance column. Similar problem is solved here. It's how to calculate row value based on the value in previous row.
So your complete query could look like this:
SELECT t1.Tran_Date, t1.Mate_Code, t1.Qty_In, t1.Qty_Out,
#b := #b + t1.Qty_In - t1.Qty_Out AS Qty_Balance
FROM
(SELECT #b := 0) AS dummy
CROSS JOIN
(SELECT Tran_Date, Mate_Code,
SUM(CASE WHEN Tran_Type = 'IN' THEN Tran_Qtyx ELSE 0 END) Qty_In,
SUM(CASE WHEN Tran_Type = 'OUT' THEN Tran_Qtyx ELSE 0 END) Qty_Out
FROM myTable
WHERE Mate_Code = 'MAT001'
GROUP BY DATE(Tran_Date)) AS t1
ORDER BY t1.Tran_Date;
NOTE: probably only think you should change here is table name and it's should work.
Here is SQL Fiddle so you can see how that's work!
GL!
You will need to structure your query into one, or pass in a parameter to the stored procedure to select which output/query you want, to restructure your query you will need something like:
`CREATE PROCEDURE `usp_GetStockCard` (IN Matecode varchar(10))
BEGIN
(select tran_date as tran_date, Mate_code as Mate_code, tran_qtyx as Qty
from TM_matbalance
where Mate_code=Matecode
and (tran_type='IN' or tran_type='OUT');
END`
Or try this if you have an ID column:
SELECT coalesce(ta.id, tb.id) as tran_id, coalesce(ta.tran_date, tb.tran_date) as tran_date, coalesce(ta.Mate_code, tb.Mate_code) as Mate_code, ta.tran_type as Qty_In, tb.tran_type as Qty_Out
from (select ta.*
from TM_matbalance ta
where ta.tran_type = 'IN'
and Mate_code=Matecode
) ta full outer join
(select tb.*
from TM_matbalance tb
where tb.tran_type = 'OUT'
and Mate_code=Matecode
) tb
on ta.id = tb.id ;
just replace "id" with the name of your ID column if you don't need to return the id column then remove coalesce(ta.id, tb.id) as tran_id

MySQL SELECT Query - Subtract a SUM() value with the combined total of two other SUM() values

I have two SELECT statements that give the values "TotalSales" and "VendorPay_Com". I want to be able to subtract VendorPay_Com from TotalSales within the one MySQL statement to get the value "Outstanding_Funds" but I haven't found a reliable way to do so.
These are my two statements:
Query 1:
SELECT SUM(Price) AS TotalSales
FROM PROPERTY
WHERE Status = 'Sold';
Query 2:
SELECT SUM(AC.Amount) AS VendorPay_Comm
FROM (
SELECT Amount FROM lawyer_pays_vendor
UNION ALL
SELECT CommissionEarned AS `Amount` FROM COMMISSION AS C WHERE C.`status` = 'Paid') AS AC
Any help on this matter would be greatly appreciated :)
You can do it as follows :
select (select ...) - (select ...)
In your example, simply :
select
(
SELECT SUM(Price) AS TotalSales
FROM PROPERTY
WHERE Status = 'Sold'
)
-
(
SELECT SUM(AC.Amount) AS VendorPay_Comm
FROM (
SELECT Amount FROM lawyer_pays_vendor
UNION ALL
SELECT CommissionEarned AS `Amount` FROM COMMISSION AS C WHERE C.`status` = 'Paid') AS AC
) AS Outstanding_Funds
Try
SELECT TotalSales-VendorPay_Comm AS Outstanding_Funds
FROM
(SELECT SUM(Price) AS TotalSales
FROM PROPERTY
WHERE Status = 'Sold') t1,
(SELECT SUM(Amount) AS VendorPay_Comm
FROM (SELECT Amount FROM lawyer_pays_vendor
UNION ALL
SELECT CommissionEarned AS Amount
FROM COMMISSION
WHERE Status = 'Paid') t0) t2
Here is sqlfiddle