Get count for each record mysql - mysql

I have 2 tables name event and checkin
It is joined with event.id to checkin.event_id
i want to get count of number of checkins in checkin for all records in event
So far i have done this and it returns the value but it returns the count for the entries in checkin table
I want to get no of checkins of each event.id
How do i get that
I am using this query right now
SELECT e.id,COUNT(*) from checkin c
LEFT JOIN event e ON (c.event_id=e.id)
GROUP by e.id
which is giving me result like this
event_id COUNT(*)
1 2
5 5
7 8
Which is fine but i want result like this
event_id COUNT(*)
1 2
2 0
3 0
4 0
5 5
6 0
7 8
Hope my question is clear now
thank you

Reverse the join and count non-null event_id:
SELECT e.d, COUNT(c.event_id) AS check_count
FROM event e LEFT OUTER JOIN checkin c ON c.event_id = e.id
GROUP BY e.event_id
Try adding COUNT(e.id) so you can compare it to COUNT(*) or COUNT(c.event_id).

use the below query with an alias for the counter
SELECT e.id,COUNT(c.*) as check_count from checkin c
LEFT JOIN event e ON (c.event_id=e.id)
GROUP by e.id
Also i recommend you to use PDO or mysqli_* functions instead of mysql_* functions that are deprecated

You can do simply as-
select event_id, count(id)
from checkin group by event_id;
If due to some specific reason you want to cross check that event table should have corresponding rows then you can do as per below-
SELECT e.id, COUNT(c.id)
FROM event AS e
JOIN checkin AS c ON c.event_id=e.id
GROUP BY e.id;
If you want to show event id even does not exist in checkin table then you can do as per below-
SELECT e.id, COUNT(c.id)
FROM event AS e
LEFT JOIN checkin AS c ON c.event_id=e.id
GROUP BY e.id;

Related

Compare scores in two tables and show those where the most recent is different

I have two tables in MariaDB where I need to show those in the left table where their current score is not the same as the most recent score in the history table.
For example:
users
id name current_score
1 Bob 4
2 Tom 5
3 Fred 3
4 Tim 3
5 Ian 4
histories
id user_id score date
1 1 3 2018-11-13
2 1 4 2018-11-12
3 1 2 2018-11-11
4 2 5 2018-11-12
In the above I would want to show Bob as his latest history is not the same as his current score but not show Tom as his is a match
I tried using something like:
SELECT u.id, u.name, u.current_score
FROM users u
where u.current_score not in
(select h.score from histories h where
h.user_id=u.id order by h.date desc limit 1)
This threw an error:
#1235 - This version of MariaDB doesn't yet support
'LIMIT & IN/ALL/ANY/SOME subquery'
If I remove the limit 1 then it returns almost all the rows in users - there are a few thousands rows in each tables but I think it should return around 50 but it is returning over 4,100 rows out of 4,285 possible rows
Determine the latest history score in a Correlated subquery, within the Select clause itself.
Group By on the user, and use HAVING clause to consider cases where current score does not match the latest score in the history
I have to use MAX() aggregation function on the score values, so that it is a valid ANSI SQL compliant GROUP BY. It does not affect anything, as respective score values are one only (thus maximum only).
Try the following instead:
SELECT u.id,
u.name,
MAX(u.current_score) AS m_current_score,
MAX((select h.score
from histories h
where h.user_id = u.id
order by h.date desc limit 1)) AS history_score
FROM users u
GROUP BY u.id, u.name
HAVING m_current_score <> history_score
One approach for what you need is using a sub-query for get the date related to the latest history entry for every user_id. After this, you can join again the table histories for get the rest of the columns associated to this latest date. This is summarized on next query:
SELECT
u.id,
u.name,
u.current_score,
h.score AS latest_score_from_history
FROM
user AS u
LEFT JOIN
-- This subquery gets the date of the latest history register for every user
(SELECT
user_id,
MAX(date) AS maxDate
FROM
histories
GROUP BY
user_id) AS latest ON latest.user_id = u.id
LEFT JOIN
histories AS h ON h.user_id = latest.user_id AND h.date = latest.maxDate
WHERE
u.current_score <> h.score

Sort order for two tables using group by

I have two tables, event and version. An event has many versions. I want to perform an inner join and get THE LAST version for each event. (Original question was here: Join two tables and apply group by, but change sort order)
I've changed the tables to this. I think it makes more sense. But I am in the same situation, I don't understand how to get the max version id per event. I'd like to understand the logic behind the solution. Feel free to give me feedback on table structure. Thanks!
Query:
SELECT e.id AS event_id,v.*
FROM events.event e
INNER JOIN events.version v
ON (v.event_id = e.id)
GROUP BY v.event_id
EVENT
Id Updated
1 03/08/18
2 06/06/18
VERSION
Id Event_id Name Description
7 1 Dinner Dinner Z
8 2 Breakfast Breakfast Y
9 2 Breakfast Breakfast X
Assuming the last version in an event is characterized by having the largest ID value, we can try the following query:
SELECT
e.id AS event_id,
v1.*
FROM event e
INNER JOIN version v1
ON e.id = v1.event_id
INNER JOIN
(
SELECT event_id, MAX(id) AS max_id
FROM version
GROUP BY event_id
) v2
ON v1.event_id = v2.event_id AND
v1.id = v2.max_id;
You will notice that the first join in the above query is what you were already doing. I simply added a join to a new subquery which finds the most recent event for each version.
select max(v.id),v.*,e.* from EVENT as e inner join VERSION as v on e.Id=v.Event_id group by v. Event_id
try the query, I think it works fine.

Select all rows present in Table A OR Table B

I would like to get the resulting row if the foreign id present in Table A or in Table B.
I have 3 tables: events, pdf_results and live_Results. I would like to select all events with pdf_results OR live_Results.
I have tried following query but it's not working when results are available in both tables.
SELECT
events.*,
live_results.id,
pdf_results.id
FROM events
LEFT JOIN pdf_results
ON pdf_results.eventId = events.id
LEFT JOIN live_Results
ON live_Results.eventId = events.id;
Here is SQL Fiddle Demo
How about just using exists?
SELECT e.*
FROM events e
WHERE EXISTS (SELECT 1 FROM pdf_results pr WHERE pr.eventId = e.id) OR
EXISTS (SELECT 1 FROM live_Results lr WHERE lr.eventId = e.id);
You can join with a UNION query:
SELECT e.*, r.result_type
FROM events AS e
JOIN (SELECT eventId, 'pdf' AS result_type FROM pdf_results
UNION ALL
SELECT eventId, 'live' AS result_type FROM live_results) AS r
ON e.id = r.eventId
Adding the result_type column allows us to know which results table it matched, and we'll get two rows if it matches both.
You could also use your original query, and add:
WHERE pdf_results.eventId IS NOT NULL OR live_results.eventId IS NOT NULL
You won't get two rows when it matches twice, but you'll be able to tell from the two eventId columns which results table it was found in.

How do I consolidate/combine data when using a SQL join?

So I have a table called Events which looks like:
Id Date Title Location
1 2014 test New York
And another table called Quote Items:
ID Item_type cost event_id
1 paper 2 1
2 water 1 1
I have a simple join query like so:
select events.title, events.id, events.location, events.date, active_quote_items.cost
from active_quote_items
left join events
on active_quote_items.event_id=events.id
Which returns the data i want but each event can have multiple qoute items. I want to merge this data so that the cost of all items is consolidated in the column after the join. Is this possible, or is something similar possible?
You need Group by and Sum aggregate
SELECT events.title,
events.id,
events.location,
events.date,
Sum(active_quote_items.cost)
FROM active_quote_items
LEFT JOIN events
ON active_quote_items.event_id = events.id
GROUP BY events.title,
events.id,
events.location,
events.date
In SQL Server, you could also use the analytic function SUM() OVER to do this:
SELECT e.title
,e.id
,e.location
,e.[DATE]
,Sum(aq.cost) OVER (PARTITION BY aq.event_id)
FROM active_quote_items aq
LEFT JOIN events e ON aq.event_id = e.id;

SUM time values in related table

I have two tables in a MySQL database, events and appointments. Each appointment has a field event_id, a start_time and an end_time column.
I'm trying to set up a query which will give me the event ids with their total amount of appointment time in minutes. For example, if an event has two appointments with the following details:
Starts at 10:00:00, Finishes at 11:30:00
Starts at 12:30:00, Finishes at 13:15:00
Then the appointments column for the event would read 135.
I know how to get a simple count of the appointments but I'm a bit stuck when it comes to working out the time. Here's what I have so far:
SELECT
events.id AS event_id,
(SELECT COUNT(id) FROM appointments WHERE event_id = events.id) AS appointment_count
FROM events
Any advice appreciated.
Thanks.
try something like this:
SELECT e.name, ap.event_id,
sum((TIME_TO_SEC(end_time) - TIME_TO_SEC(start_time))/60) AS dif
FROM events e LEFT JOIN appointment ap ON e.id = ap.event_id
GROUP BY e.name, ap.event_id
ORDER BY 2;
Example..
try this
SELECT A.*,count(B.*) as count
FROM table_event A
JOIN table_appointment B ON A.event_id = B.event_id
GROUP BY B.event_id