Count Total from Multiple Table - mysql

I have 3 tables (ticket1, ticket2, ticket3) that contain same field:
ticket1: ticket2: ticket2:
======== ======== ========
ticket_id ticket_id ticket_id
status status status
And my query just like this:
("SELECT (SELECT COUNT( * ) FROM `ticket1` WHERE `status` =9) AS done,
(SELECT COUNT( * ) FROM `ticket1` WHERE `status` =10) AS Incomplete,
(SELECT COUNT( * ) FROM `ticket1` WHERE `status` =2) AS New")
This is to count ticket and filter by status.
And my question is, how i can count all ticket into total Done, Incomplete, and New from ticket1, ticket2, ticket3.
Help me guys, thanks..

I guess the 3d table's name is ticket3, right?
SELECT
(SELECT COUNT(*) FROM `ticket1` WHERE `status` = 9) +
(SELECT COUNT(*) FROM `ticket2` WHERE `status` = 9) +
(SELECT COUNT(*) FROM `ticket3` WHERE `status` = 9) AS TotalDone,
(SELECT COUNT(*) FROM `ticket1` WHERE `status` = 10) +
(SELECT COUNT(*) FROM `ticket2` WHERE `status` = 10) +
(SELECT COUNT(*) FROM `ticket3` WHERE `status` = 10) AS TotalIncomplete,
(SELECT COUNT(*) FROM `ticket1` WHERE `status` = 2) +
(SELECT COUNT(*) FROM `ticket2` WHERE `status` = 2) +
(SELECT COUNT(*) FROM `ticket3` WHERE `status` = 2) AS TotalNew

Try this.
select status, count(1) from
(select * from ticket1
union all
select * from ticket2
union all
select * from ticket3) group by status;
Let me know if you face any issues

you could select from union all
select sum(case when status = 9 then 1 else 0 end) done,
sum(case when status = 10 then 1 else 0 end) Incomplete,
sum(case when status = 2 then 1 else 0 end) New,
sum(case when status in (9,10,2) then 1 else 0 end) deon_incomplete_new,
count(*) tot
from (
select ticket_id, status from ticket1
union all
select ticket_id, status from ticket2
union all
select ticket_id, status from ticket2
) t

I would suggest:
select sum(case when status = 9 then cnt else 0 end) as done,
sum(case when status = 10 then cnt else 0 end) as incomplete,
sum(case when status = 2 then cnt else 0 end) as new
from ((select status, count(*) as cnt from ticket1 group by status
) union all
(select status, count(*) as cnt from ticket2 group by status
) union all
(select status, count(*) as cnt from ticket3 group by status
)
) t;
Or, you might consider putting the values in separate rows using group by.
If performance is an issue and you have lots of other tickets statuses (or more specifically lots of rows with different statuses), then where status in (2, 9, 10) in each of the subqueries might help.

Related

how to subtract to sum(produced from same table) in MYSQL?

amount group
--------------
100 'a'
40 'b'
30 'a'
50 'b'
query output:
diff(a-b)
---------
40
how to do it in MYSQL?
You can simply:
SELECT (SELECT SUM(amount) FROM t WHERE `group` = 'a') -
(SELECT SUM(amount) FROM t WHERE `group` = 'b') AS diff
Or:
SELECT SUM(CASE
WHEN `group` = 'a' THEN amount
WHEN `group` = 'b' THEN -amount
END) AS diff
FROM t

Count union of two table that has subquery

I have this working query. It has count with subquery.
SELECT
COUNT(*) AS total
FROM
(SELECT
COUNT(aset)
FROM
`public_1`
WHERE `public_1`.`aset` NOT IN
(SELECT
asset_code
FROM
application_detail
WHERE application_id = 6)
AND org_id = 7
AND status_id = 8
GROUP BY aset) t
now I need to union with different table and get the total from both table. This code could get count record but the value is incorrect.
SELECT
COUNT(*) AS total
FROM
(SELECT
COUNT(aset)
FROM
`public_1`
WHERE `public_1`.`aset` NOT IN
(SELECT
asset_code
FROM
application_detail
WHERE application_id = 6)
AND org_id = 7
AND status_id = 8
UNION
SELECT
COUNT(aset)
FROM
`public_2`
WHERE `public_2`.`aset` NOT IN
(SELECT
asset_code
FROM
application_detail
WHERE application_id = 6)
AND org_id = 7
AND status_id = 8
GROUP BY aset) z
Please assist me in getting the query correct. Thanks in advance
Use SELECT COUNT(DISTINCT aset) to get your counts, and then add them together.
SELECT t1.total + t2.total AS total
FROM (
SELECT COUNT(DISTINCT aset) AS total
FROM `public_1`
WHERE `public_1`.`aset` NOT IN
(SELECT
asset_code
FROM
application_detail
WHERE application_id = 6)
AND org_id = 7
AND status_id = 8) AS t1
CROSS JOIN (
SELECT COUNT(DISTINCT aset) AS total
FROM `public_2`
WHERE `public_2`.`aset` NOT IN
(SELECT
asset_code
FROM
application_detail
WHERE application_id = 6)
AND org_id = 7
AND status_id = 8) AS t2

MySql GROUP BY Max Date

I have a table called votes with 4 columns: id, name, choice, date.
****id****name****vote******date***
****1*****sam*******A******01-01-17
****2*****sam*******B******01-05-30
****3*****jon*******A******01-01-19
My ultimate goal is to count up all the votes, but I only want to count 1 vote per person, and specifically each person's most recent vote.
In the example above, the result should be 1 vote for A, and 1 vote for B.
Here is what I currently have:
select name,
sum(case when uniques.choice = A then 1 else 0 end) votesA,
sum(case when uniques.choice = B then 1 else 0 end) votesB
FROM (
SELECT id, name, choice, max(date)
FROM votes
GROUP BY name
) uniques;
However, this doesn't work because the subquery is indeed selecting the max date, but it's not including the correct choice that is associated with that max date.
Don't think "group by" to get the most recent vote. Think of join or some other option. Here is one way:
SELECT v.name,
SUM(v.choice = 'A') as votesA,
SUM(v.choice = 'B') as votesB
FROM votes v
WHERE v.date = (SELECT MAX(v2.date) FROM votes v2 WHERE v2.name = v.name)
GROUP BY v.name;
Here is a SQL Fiddle.
Your answer are close but need to JOIN self
Subquery get Max date by name then JOIN self.
select
sum(case when T.vote = 'A' then 1 else 0 end) votesA,
sum(case when T.vote = 'B' then 1 else 0 end) votesB
FROM (
SELECT name,Max(date) as date
FROM T
GROUP BY name
) AS T1 INNER JOIN T ON T1.date = T.date
SQLFiddle
Try this
SELECT
choice,
COUNT(1)
FROM
votes v
INNER JOIN
(
SELECT
id,
max(date)
FROM
votes
GROUP BY
name
) tmp ON
v.id = tmp.id
GROUP BY
choice;
Something like this (if you really need count only last vote of person)
SELECT
sum(case when vote='A' then cnt else 0 end) voteA,
sum(case when vote='B' then cnt else 0 end) voteB
FROM
(SELECT vote,count(distinct name) cnt
FROM (
SELECT name,vote,date,max(date) over (partition by name) maxd
FROM votes
)
WHERE date=maxd
GROUP BY vote
)
PS. MySQL v 8
select
name,
sum( case when choice = 'A' then 1 else 0 end) voteA,
sum( case when choice = 'B' then 1 else 0 end) voteB
from
(
select id, name, choice
from votes
where date = (select max(date) from votes t2
where t2.name = votes.name )
) t
group by name
Or output just one row for the total counts of VoteA and VoteB:
select
sum( case when choice = 'A' then 1 else 0 end) voteA,
sum( case when choice = 'B' then 1 else 0 end) voteB
from
(
select id, name, choice
from votes
where date = (select max(date) from votes t2
where t2.name = votes.name )
) t
Based on #d-shish solution, and since introduction (in MySQL 5.7) of ONLY_FULL_GROUP_BY, the GROUP BY statement must be placed in subquery like this :
SELECT v.`name`,
SUM(v.`choice` = 'A') as `votesA`,
SUM(v.`choice` = 'B') as `votesB`
FROM `votes` v
WHERE (
SELECT MAX(v2.`date`)
FROM `votes` v2
WHERE v2.`name` = v.`name`
GROUP BY v.`name` # << after
) = v.`date`
# GROUP BY v.`name` << before
Otherwise, it won't work anymore !

How to select rows where for same `userid` other field has specific values?

I have this kind of table (simplified):
orders sample data below
---------------------------------------------
id INT: 1 2 3 4 5
userid INT 10 10 10 20 20
status CHAR(1) A A B A C
and want to select all orders where for each userid status is IN ('A','B') but have no orders at all IN ('C','D').
So output for above data would give orders with ID=1, 2 and 3. User ID=10 have orders A and B, but no C or D.
In other words: Select orders for customers who have orders with status A or B, but none of statuses C or D.
I started with this:
SELECT
xcart_orders.orderid,
xcart_orders.*
FROM xcart_orders
JOIN (
select count(*) as bad_statuses, userid from xcart_orders
where status in ('C','D')
group by userid
) bo
ON bo.userid=xcart_orders.userid
JOIN (
select count(*) as good_statuses, userid from xcart_orders
where status in ('A','B')
group by userid
) bo2
ON bo2.userid=xcart_orders.userid
WHERE bo2.good_statuses>0 and bo.bad_statuses=0
but think count(*) won't return zero for 'bad' statuses, so I get no results.
You have an aggregation without GROUP BY and for check the result you need us HAVING instead of WHERE
SELECT
xcart_orders.orderid,
xcart_orders.*,
SUM(CASE WHEN xcart_orders.status in ('C','D') THEN 1 ELSE 0 END) AS bad_statuses,
SUM(CASE WHEN xcart_orders.status in ('A','B') THEN 1 ELSE 0 END) AS good_statuses
FROM xcart_orders
GROUP BY orderid
HAVING bad_statuses = 0
AND good_statuses > 0
Please be aware the fields you get from xcart_orders.* will be random (or non deterministc) if you need a particular one you need to order it first.
First you GROUP BY user_id to check if have any status different to 'A', 'B'
Then you select orders from those user_id:
SQL DEMO
SELECT `user_id`
FROM orders1
GROUP BY `user_id`
HAVING COUNT(*) = COUNT(CASE WHEN `status` IN ('A', 'B') THEN 1 END);
SELECT *
FROM orders1
WHERE `user_id` IN (SELECT `user_id`
FROM orders1
GROUP BY `user_id`
HAVING COUNT(*) = COUNT(CASE WHEN `status` IN ('A', 'B') THEN 1 END)
);
OUTPUT

MySQL SUM DISTINCT with Conditional

I need to gather sums using conditional statements as well as DISTINCT values
with a multiple GROUP BY. The example below is a simplified version of a much much more complex query.
Because the real query is very large, I need to avoid having to drastically re-write the query.
DATA
Contracts
id advertiser_id status
1 1 1
2 2 1
3 3 2
4 1 1
A Query that's close
SELECT
COUNT( DISTINCT advertiser_id ) AS advertiser_qty,
COUNT( DISTINCT id ) AS contract_qty,
SUM( IF( status = 1, 1, 0 ) ) AS current_qty,
SUM( IF( status = 2, 1, 0 ) ) AS expired_qty,
SUM( IF( status = 3, 1, 0 ) ) AS other_qty
FROM (
SELECT * FROM `contracts`
GROUP BY advertiser_id, id
) AS temp
Currently Returns
advertiser_qty contract_qty current_qty expired_qty other_qty
3 4 3 1 0
Needs to Return
advertiser_qty contract_qty current_qty expired_qty other_qty
3 4 2 1 0
Where current_qty is 2 which is the sum of records with status = 1 for only DISTINCT advertiser_ids and each sum function will need the same fix.
I hope someone has a simple solution that can plug into the SUM functions.
-Thanks!!
try this
SELECT
COUNT( DISTINCT advertiser_id ) AS advertiser_qty,
COUNT( DISTINCT id ) AS contract_qty,
(select count(distinct advertiser_id) from contracts where status =1
) AS current_qty,
SUM( IF( status = 2, 1, 0 ) ) AS expired_qty,
SUM( IF( status = 3, 1, 0 ) ) AS other_qty
FROM (
SELECT * FROM `contracts`
GROUP BY advertiser_id, id
) AS temp
DEMO HERE
EDIT:
you may look for this without subselect.
SELECT COUNT(DISTINCT advertiser_id) AS advertiser_qty,
COUNT(DISTINCT id) AS contract_qty,
COUNT(DISTINCT advertiser_id , status = 1) AS current_qty,
SUM(IF(status = 2, 1, 0)) AS expired_qty,
SUM(IF(status = 3, 1, 0)) AS other_qty
FROM (SELECT *
FROM `contracts`
GROUP BY advertiser_id, id) AS temp
DEMO HERE