Combining two Count Queries into one - mysql

I have theses two queries
SELECT course,
COUNT(*) AS countp
FROM table1
WHERE pickout='Yes'
GROUP BY course
SELECT course,
COUNT(*) AS countw
FROM table1
WHERE pickout='Yes' AND result='Won'
GROUP BY course
what I am trying to achieve is a table with three columns Course, Countp, Countw but I am having trouble combining the two into one query.
Basically I am looking for a list of course with number of picks and then number of wins.

In MySQL the result of conditions evaluate to 1 or 0. You can sum that up
SELECT course,
sum(pickout='Yes') AS countp,
sum(pickout='Yes' AND result='Won') AS countw
FROM table1
GROUP BY course

Try the following SQL:
SELECT
Course,
COUNT(*) AS CountP,
SUM(CASE WHEN result='Won' THEN 1 ELSE 0 END) AS CountW
FROM table1
WHERE pickout = 'Yes'
GROUP BY Course

try this:
select a.course,a.countp ,b.countw from (SELECT course, COUNT(*) AS countp FROM table1 WHERE pickout='Yes' GROUP BY course)a full join
(SELECT course, COUNT(*) AS countw FROM table1 WHERE pickout='Yes' AND result='Won' GROUP BY course)b
a.course=b.course

Related

Count Distinct on multiple values within same column in SQL Aggregation

Objective:
I wanted to show the number of distinct IDs for any combination selected.
In the below example, I have data at a granular level: ID level data.
I wanted to show the number of distinct IDs for each combination.
For this, I use count distinct which will give me '1' for the below combinations.
But let's say if I wanted to find the number of IDs who made both E-commerce and Face to face transactions, in that case, if I just use this data, I would be showing the sum of E-comm and Face to face and the result would be '2' instead of '1'.
And this is not limited to Ecom/Face to face. I wanted to apply the same logic for all columns.
Please let me know if you have any other alternative approach to address this issue.
First aggregate in your table to get the distinct ids for each TranType:
SELECT TranType, COUNT(DISTINCT id) counter_distinct
FROM tablename
GROUP BY TranType
and then join to the table:
SELECT t.*, g.counter_distinct
FROM tablename t
INNER JOIN (
SELECT TranType, COUNT(DISTINCT id) counter_distinct
FROM tablename
GROUP BY TranType
) g ON g.TranType = t.TranType
Or use a correlated subquery:
SELECT t1.*,
(SELECT COUNT(DISTINCT t2.id) FROM tablename t2 WHERE t2.TranType = t1.TranType) counter_distinct
FROM tablename t1
But let's say if I wanted to find the number of IDs who made both E-commerce and Face to face transactions, in
You can get the list of ids using:
select id
from t
where tran_type in ('Ecomm', 'Face to face')
group by id
having count(distinct tran_type) = 2;
You can get the count using a subquery:
select count(*)
from (select id
from t
where tran_type in ('Ecomm', 'Face to face')
group by id
having count(distinct tran_type) = 2
) i;

Two different counts in the one query

I have a web page that displays requests received by each user (Firstname) that are separated into 1 of 4 lists based on 4 separate queries which rely on a WHERE statement to check the value of the ‘status’ column (incoming, playlisted, sidelisted, played).
This solution works for the ‘played’ list.
SELECT
t1.FirstName, count(*)
FROM
RequestsTable t1
WHERE t1.status = 'played'
GROUP BY t1.FirstName;
but the WHERE statement doesn’t allow it to work for requests that are in the other 3 lists.
Two counts are required within each of the 4 lists to show
i) the total number of requests made by each user.
ii) the number of requests made by each user that have been ’played’.
All of my attempts to use JOINS and CASE statements have been defeated by the WHERE statement which limits the counts to the records within any 1 of the 4 lists.
Remove the WHERE statement and put the status conditions in the COUNT:
SELECT
t1.FirstName,
count(*) as totalCount,
count(IF(t1.status = 'played',1,null)) as playedCount
FROM
RequestsTable t1
GROUP BY t1.FirstName;
SELECT
t1.FirstName, count(*) cnt ,0 played,0 played2
FROM
RequestsTable t1
GROUP BY t1.FirstName
union
SELECT
t1.FirstName, 0 cnt ,count(*) played,0 played2
FROM
RequestsTable t1
WHERE t1.status = 'played'
GROUP BY t1.FirstName
union
SELECT
t1.FirstName, 0 cnt,0 played ,count(*) played2
FROM
RequestsTable t1
WHERE t1.status = 'played2'
GROUP BY t1.FirstName
Try above query.
Hope this will helps.

Select something from mysql database and order it by count (where)

I have a problem with selecting something from my database. Here is the sql sentence:
SELECT name
FROM table1
JOIN table2
ON table1.id=table2.advid
GROUP BY advid
ORDER BY COUNT(table2.likes) ASC
This will output name with the least table2.likes to the highest value of table2.likes
The problem is that table2.likes contain both likes and dislikes. Likes are marked with 1, and dislikes are marked with 2 in the table.
Currently, if there is...
...written in the table, the syntax will count both likes and dislikes so the result would be 6. I would need this result to be zero, which means when counting, dislikes have to be deduced from the number of likes. Which also means this part of the sentence: ORDER BY COUNT(table2.likes) ASC would have to be changed, but I don't know how.
Use conditional aggregation with SUM():
SELECT name
FROM table1 t1 JOIN
table2 t2
ON t2.id = t2.advid
GROUP BY name
ORDER BY SUM(CASE WHEN t2.likes = 1 THEN 1 ELSE -1 END) ASC;
Note: I changed the GROUP BY to be by name. The GROUP BY columns should match the columns you are selecting.
Use a case expression to count 1 for likes and -1 for dislikes. It is considered good style and less error-prone not to join and then aggregate, but to join the already aggregated data instead.
select t1.name, t2.sumlikes
from table1 t1
join
(
select advid, sum(case when likes = 1 then 1 else -1 end) as sumlikes
from table2
group by advid
) t2 on t2.advid = t1.id
order by sumlikes;
If you want to list names without like entries, too, then turn the join into a left outer join and select coalesce(t2.sumlikes, 0) instead.

How to get AS two separate selectors with UNION?

As sadly SQL is my weakest skill.
I'm trying to use UNION in a VIEW, where I can get statistics from two different tables with one query.
SELECT COUNT(*) AS `customer_count` FROM `Customers`
UNION
SELECT COUNT(*) AS `supplier_count` FROM `Suppliers`;
[Demo table]
However, it only returns customer_count, with two rows. Is there anyway, to make this work, so it returns customer_count and supplier_count separately?
You would need a cross join to see the results adjacent to each other in one row. So you would select from both the tables without a join condition.
select * from
(select count(*) as customer_count from Customers) x,
(select count(*) as supplier_count from Suppliers) y
select
(SELECT COUNT(*) FROM Customers) as customer_count,
(SELECT COUNT(*) FROM Suppliers) AS supplier_count
Using your Table Demo.
The key is use alias so the field names match on each union select.
In this case TableSource and Total
SELECT 'Customer' as TableSource, Count(City) as Total FROM Customers
UNION
SELECT 'Suppliers' as TableSource, Count(City) as Total FROM Suppliers;
CREATE VIEW `vw_count` AS
select (select count(0) from `tbl`) AS `customer_count`,
(select count(0) from `tbl2`) AS `supplier_count`;

MySQL efficient and correct linking of GROUP BY results

is there some efficient way how to write queries that join various results of GROUP BYs on a common table? How MySQL handles merging results of aggreagate functions ona a subGROUP with full fields from original table?
i am using this and its slow (and i need also other condition than CONDITION=1)
SELECT a.CID,a.AS_ALL,b.AS_ACTIVE FROM
(SELECT CID,COUNT(DISTINCT RAID) AS AS_ALL FROM MYTABLE GROUP BY CID) a
LEFT JOIN
(SELECT CID,COUNT(DISTINCT RAID) AS AS_ACTIVE FROM MYTABLE WHERE CONDITION=1 GROUP BY CID ) b ON a.CID=b.CID;
also is it save to use something like?? will MySQL always correctly merge COLUMN_A with results of aggregation?
SELECT COLUMN_A COUNT(DISTINCT COLUMN_A), SUM(COLUMN_A),SUM(COLUMN_B) FROM ATABLE WHERE CONDITION=1 GROUP BY COLUMN_C
Thank you for advice
Try this:
SELECT CID,COUNT(DISTINCT RAID) AS AS_ALL,SUM(IF(CONDITION=1, 1, 0)) AS AS_ACTIVE
FROM MYTABLE GROUP BY CID