Request to count the number of people at the event - mysql

I'm trying to count the number of people at the hackathon. At the moment I am able to count the number of sponsors, organizers, customers and teams of participants, but I also need to count the number of judges and the participants themselves (that is, I do not need to count the teams)
Here is my current query
select h.hakaton_name, count(*) as people_count
from hakatons as h
join (select hakaton_id from sponsors_hakatons_ad
union all
select hakaton_id from mentors_hakatons_ad
union all
select hakaton_id from organizers_hakatons_ad
union all
select hakaton_id from customers_hakatons_ad
union all
select hakaton_id from teams_hakatons_ad) as dt
on h.hakaton_id = dt.hakaton_id
group by h.hakaton_name
order by people_count desc
limit 5
My Database schema

Related

Replacing a union in MySQL

I’m trying to retrieve the number of unique users that have made a purchase in a monthly basis. This sounds simple but the problem here is that we have three type of products and the purchases of these products are on different tables in which the only common key is the user_id, so in order to find out unique users I have to query the three tables separately, union the results and execute a count distinct.
Here’s an example of what I’m doing right now:
SELECT
month,
count(distinct user_id) as users
FROM
(
SELECT
DATE_FORMAT(purchase_date,’%Y-%m) as month,
user_id
FROM purchases_a
UNION
SELECT
DATE_FORMAT(purchase_date,’%Y-%m) as month,
user_id
FROM purchases_b
UNION
SELECT
DATE_FORMAT(purchase_date,’%Y-%m) as month,
user_id
FROM purchases_c
)
GROUP BY 1
Is this the only way to go? This query takes forever. Thanks!
One method is to use union all in a subquery and then aggregate:
select DATE_FORMAT(purchase_date, '%Y-%m') as month,
count(distinct user_id)
from ((select user_id, purchase_date from purchases_a) union all
(select user_id, purchase_date from purchases_b) union all
(select user_id, purchase_date from purchases_c)
) p
group by month

MySQL query to count zero value using group by in the same table

Here's my "customers" table:
To get number of enquiries per for a particular month and year, I'm using following query:
SELECT YEAR(customer_date) AS Year, MONTH(customer_date) AS Month, COUNT(customer_id) AS Count FROM customers WHERE customer_product = 6 GROUP BY YEAR(customer_date), MONTH(customer_date)
I get following result:
You can see that as there is no enquery in the April month, so no row fetched for month number 4. But I want 0 value in Count column if there is no record found in that particular month and year.
This is what I want:
One option uses a calendar table to represent all months and years, even those which do not appear in your data set:
SELECT
t1.year,
t2.month,
COUNT(c.customer_id) AS Count
FROM
(
SELECT 2017 AS year UNION ALL
SELECT 2018
) t1
CROSS JOIN
(
SELECT 1 AS month UNION ALL
SELECT 2 UNION ALL
SELECT 3 UNION ALL
SELECT 4 UNION ALL
SELECT 5 UNION ALL
SELECT 6 UNION ALL
SELECT 7 UNION ALL
SELECT 8 UNION ALL
SELECT 9 UNION ALL
SELECT 10 UNION ALL
SELECT 11 UNION ALL
SELECT 12
) t2
LEFT JOIN customers c
ON t1.year = YEAR(c.customer_date) AND
t2.month = MONTH(c.customer_date)
WHERE
c.customer_product = 6
GROUP BY
t1.year,
t2.month
ORDER BY
t1.year,
t2.month;
Note: The above query can probably be made faster by actually creating dedicated calendar tables in your MySQL schema.
The following index on the customers table might help:
CREATE INDEX idx ON customers(customer_product, customer_id);
This might make the join between the calendar tables and customers faster, assuming that the customer_product = 6 condition is restrictive.

How to display only value that occurs second highest number of times?

Write a query to display the customer name who visited the second highest number of times
select customer_id,count(*) from booking group by customer_id ;
using this query i got the count of number of visits for each customer as shown below
CUSTOMER_ID,COUNT(*)
C001,6
C002,1
C003,1
C004,1
C005,4
but i want to display only c005 since he has visited the second maximum time
SELECT customer_id, COUNT(*)
FROM booking
GROUP BY customer_id
HAVING COUNT(*) <> (SELECT MAX(t.custCount)
FROM (SELECT COUNT(*) AS custCount
FROM booking
GROUP BY customer_id) t )
ORDER BY COUNT(*) DESC
LIMIT 1
As a side note, this won't work if there are ties for second place. In this case, you use the above query as a condition in the WHERE clause, e.g.
SELECT customer_id
FROM booking
GROUP BY customer_id
HAVING COUNT(*) = (query given above)
You can use a outer query and filter the same like
select customer_id from (
select customer_id,
count(*) as datacount
from booking
group by customer_id ) xxx
order by datacount desc
limit 1;

Combining Two Select Sum Statements Into One

I have two statements within my table which work fine individually like this:
SELECT fee_earner, (SUM(fe_fees)) AS Total
FROM fees
GROUP BY fee_earner
order by Total desc;
SELECT supervisor, (SUM(sv_fees)) AS Total
FROM fees
GROUP BY supervisor
order by Total desc;
But there are some cases where the fee_earner and supervisor fields have the same person as the data, is there a way to combine these two statements into one to get the overall totals?
You can use union all for this:
SELECT person, sum(fe_fees) as fe_fees, sum(sv_fees) as sv_fees,
(sum(fe_fees) + sum(sv_fees)) as total
FROM ((select fee_earner as person, fe_fees as fe_fees, 0 as sv_fees, 'earner' as which
from fees
) union all
(select supervisor as person, 0 as fe_fees, sv_fees as sv_fees, 'supervisor' as which
from fees
)
) t
GROUP BY person
order by Total desc;
select
fee_earner, SUM(fe_fees) as total, SUM(sv_fees) as total2,
SUM(fe_fees) + SUM(sv_fees) as wholeTotal
from
fees
group by
fee_earner, supervisor
order by
Total desc;

Mysql Query [0002] [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
So I got two Mysql tables and I'm having a hard time doing following query.
Query: Get the the sales value per month, per city
users
id, name, city
sales
*id, user_id, name, amount, date (datetime)*
I started with SELECT MONTHNAME(datetime) AS month GROUP BY month.
Thanks in advance!
Assuming you want a figure of 0 for any month and / or city which doesn't have any sales, but where there are sales for other cities for that month then something like this:-
Cross join a pair of subselects, one to get a list of the months used and one to get a list of the cities, then join those against the records to get the amounts for that month / city, and sum those amounts up:-
SELECT Sub1.YearMonth, Sub2.city, SUM(sales.amount)
FROM (SELECT DISTINCT EXTRACT(YEAR_MONTH FROM `date`) AS YearMonth
FROM sales) Sub1
CROSS JOIN (SELECT DISTINCT city FROM users) Sub2
LEFT OUTER JOIN sales ON Sub1.YearMonth = EXTRACT(YEAR_MONTH FROM sales.`date`)
LEFT OUTER JOIN users ON sales.user_id = users.id AND Sub2.city = sales.city
GROUP BY Sub1.YearMonth, Sub2.city
ORDER BY Sub1.YearMonth, Sub2.city
Down side of this is that if you have a month where nothing was sold to anybody then this month will not appear at all. To get around this you would need to change the subselect for the months to instead take a start date and add a range of numbers to it to get each month.
An example of generating a range is as follows:-
SELECT Sub1.YearMonth, Sub2.city, SUM(sales.amount)
FROM (SELECT EXTRACT(YEAR_MONTH FROM DATE_ADD('2009-01-01', INTERVAL a.i*100+b.i*10+c.i MONTH)) AS aMonth
FROM (SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) a,
(SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) b,
(SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) c
WHERE DATE_ADD('2009-01-01', INTERVAL a.i*100+b.i*10+c.i MONTH) <= '2014-12-01') Sub1
CROSS JOIN (SELECT DISTINCT city FROM users) Sub2
LEFT OUTER JOIN sales ON Sub1.YearMonth = EXTRACT(YEAR_MONTH FROM sales.`date`)
LEFT OUTER JOIN users ON sales.user_id = users.id AND Sub2.city = sales.city
GROUP BY Sub1.YearMonth, Sub2.city
ORDER BY Sub1.YearMonth, Sub2.city
This example is giving every month between 2009-01-01 and 2014-12-01 inclusive, then getting all the sales by city for that range. It will cope with a range of up to 1000 months.
Hey noob (nice name btw) :D
Try this one, I've added the YEAR() on the GROUP BY clause since month numbers are repeating per year, and I suppose you do not want the sum of sales of records with the same month but different in year. You can just omit the year on the SELECT statement if you do not want it.
SELECT YEAR(S.date) AS Year
, MONTHNAME(S.date) AS Month
, U.city
, SUM(S.amount) AS SalesPerMonthPerCity
FROM sales S
INNER JOIN users U ON U.id = S.user_id
GROUP BY YEAR(S.date), MONTH(S.date), U.city
You have an SQL Fiddle test page so you and others can try the solution.
This is the query in question:
SELECT MONTHNAME(`date`) AS Monthly
, `city`
, SUM(`amount`) AS Profit
FROM sales
INNER JOIN users ON userid = idu
GROUP BY MONTHNAME(`date`), `city` WITH ROLLUP
Used the WITH ROLLUP to add a subtotal by month and a grand total at the end.
PS: I agree with the comments, you should show some more effort on solving your problem, you are not new on SO so you should be aware of that ;)