My SQL's more than a little rusty, and I'm having trouble getting this to work, so any assistance would be greatly appreciated.
I've got three tables:
sessions
---------------
id
session_visits
---------------
id | session_id
searches
---------------
id | session_visit_id
And I want to get a list of all sessions with the total visits and searches for each sessions, which is linked by the session_visits table. I can get the visits fine, but am having trouble getting the total of searches for each session too.
So far I've got
SELECT *,(SELECT Count(*)
FROM session_visits
WHERE session_id = sessions.id) AS num_visits,
(SELECT Count(*)
FROM searches
WHERE session_visit_id = (SELECT * FROM session_visits
WHERE session_id = sessions.id)) AS total_searches
FROM sessions
Which is failing on every count! Am I going about this the right way or am I fundamentally doing it wrong?
You can do this in one query, by joining the 3 tables together, and then use aggregates COUNT DISTINCT (to eliminate duplicated) and COUNT to get the total number of rows for the child and grandchild rows respectively, grouped by the Sessionid.
SELECT s.id AS SessionId, COUNT(DISTINCT sv.id) AS SessionVisits, COUNT(sr.ID) AS Searches
FROM sessions s
LEFT JOIN session_visits sv
ON s.id = sv.session_id
LEFT JOIN searches sr
ON sr.session_visit_id = sv.id
GROUP BY s.id;
SqlFiddle here
(Edit : Changed to left outer joins to handle scenarios where there are no visits for session, or no searches per visit)
query generates error because of column name is not mentioned in query
Operand should contain 1 column
and try with IN
Related
Sql fidle here.
SELECT UserId,totalLikes FROM Users
LEFT JOIN(select ownerId, PostId from Posts) a ON ownerId = UserId
LEFT JOIN(select idOfPost, count(idOfPost) AS totalLikes from Likes) b ON idOfPost = PostId
WHERE UserId = 120 GROUP BY UserId
This is a simplified part of the query that i am using, on the fiddle it works exactly how i need it to, it counts every idOfPost as a like for every post that belongs to the user specified, in this case where UserId = 120
and it groups the result in a single row.
But when i run this in WAMP i am getting the following error #1140 this is incompatible with sql_mode=only_full_group_by witch i think is because i need to group by PostId as well, but if i do that i get multiple rows, naturally because the id of the posts are different but i want to have it in a single row.
So my questions are: Should i disable the sql_mode=only_full_group_by witch i'm not really sure what impact would have, or is my tables structure at fault and it needs to be changed, maybe including the UserId in the Likes table, or my query is at fault and needs to be changed?
mysql version 5.7.14 on WAMP
Use GROUP BY in the subquery and sum() aggregate in the main query:
SELECT UserId, sum(totalLikes) AS totalLikes
FROM Users
LEFT JOIN Posts a ON ownerId = UserId
LEFT JOIN (
select idOfPost, count(idOfPost) AS totalLikes
from Likes
group by idOfPost) b ON idOfPost = PostId
WHERE UserId = 120
GROUP BY UserId
SqlFiddle.
I tried to write a query, but unfortunately I didn't succeed.
I want to know how many packages delivered over a given period by a person.
So I want to know how many packages were delivered by John (user_id = 1) between 01-02-18 and 28-02-18. John drives another car (another plate_id) every day.
(orders_drivers.user_id, plates.plate_name, orders.delivery_date, orders.package_amount)
I have 3 table:
orders with plate_id delivery_date package_amount
plates with plate_id plate_name
orders_drivers with plate_id plate_date user_id
I tried some solutions but didn't get the expected result. Thanks!
Try using JOINS as shown below:
SELECT SUM(o.package_amount)
FROM orders o INNER JOIN orders_drivers od
ON o.plate_id=od.plate_id
WHERE od.user_id=<the_user_id>;
See MySQL Join Made Easy for insight.
You can also use a subquery:
SELECT SUM(o.package_amount)
FROM orders o
WHERE EXISTS (SELECT 1
FROM orders_drivers od
WHERE user_id=<user_id> AND o.plate_id=od.plate_id);
SELECT sum(orders.package_amount) AS amount
FROM orders
LEFT JOIN plates ON orders.plate_id = orders_drivers.plate_id
LEFT JOIN orders_driver ON orders.plate_id = orders_drivers.plate_id
WHERE orders.delivery_date > date1 AND orders.delivery_date < date2 AND orders_driver.user_id = userid
GROUP BY orders_drivers.user_id
But seriously, you need to ask questions that makes more sense.
sum is a function to add all values that has been grouped by GROUP BY.
LEFT JOIN connects all tables by id = id. Any other join can do this in this case, as all ids are unique (at least I hope).
WHERE, where you give the dates and user.
And GROUP BY userid, so if there are more records of the same id, they are returned as one (and summed by their pack amount.)
With the AS, your result is returned under the name 'amount',
If you want the total of packageamount by user in a period, you can use this query:
UPDATE: add a where clause on user_id, to retrieve John related data
SELECT od.user_id
, p.plate_name
, SUM(o.package_amount) AS TotalPackageAmount
FROM orders_drivers od
JOIN plates p
ON o.plate_id = od.plate_id
JOIN orders o
ON o.plate_id = od.plate_id
WHERE o.delivery_date BETWEEN convert(datetime,01/02/2018,103) AND convert(datetime,28/02/2018,103)
AND od.user_id = 1
GROUP BY od.user_id
, p.plate_name
It groups rows on user_id and plate_name, filter a period of delivery_date(s) and then calculate the sum of packageamount for the group
I have two tables which join themselves by a field called user_id. The first table called sessions can have multiple lines for the same day. I'm trying to find a way of selecting the total of that sessions without repeating the days (sort of).
Example:
Table sessions
ID | user_id | datestart
1 1 2014-08-05
2 1 2014-08-05
3 2 2014-08-05
As you can see there are two lines that are repeated (the first and second). If I query SELECT COUNT(sess.id) AS total this will retrieve 3, but I want it to retrieve 2 because the first two lines have the same user_id so it must count as one.
Using the clause Group By will retrieve two different lines: 2 and 1, which is also incorrect.
You can view a full example working at SQLFiddle.
Is there anyway of solving this only by query or do I need to do it by language?
I think you are looking for count(distinct):
SELECT COUNT(distinct user_id) AS total
FROM sessions sess INNER JOIN
users user
ON user.id = sess.user_id
WHERE user.equipment_id = 1 AND
sess.datestart = CURDATE();
If I understand the problem correctly, you want the number of users with sessions, rather than number of unique sessions. Use DISTINCT:
SELECT COUNT(DISTINCT(user_id)) FROM sessions,users WHERE user_id=users.id
Try this way:
SELECT COUNT(distinct sess.user_id) AS total
FROM sessions AS sess
INNER JOIN users AS user ON user.id = sess.user_id
WHERE user.equipment_id = 1 AND sess.datestart = CURDATE()
Sql Fiddle
I have to tables in my database, the first one (participants) look just like that:
And I have another called votes in which I can vote for any participants.
So my problem is that I'm trying to get all the votes of each participant but when I execute my query it only retrieves four rows sorted by the COUNT of votes, And the other remaining are not appearing in my query:
SELECT COUNT(DISTINCT `votes`.`id`) AS count_id, participants.name
AS participant_name FROM `participants` LEFT OUTER JOIN `votes` ON
`votes`.`participant_id` = `participants`.`id` GROUP BY votes.participant_id ORDER BY
votes.participant_id DESC;
Retrieves:
I think the problem is that you're grouping by votes.participant_id, rather than participants.id, which limits you to participants with votes, the outer join notwithstanding. Check out http://sqlfiddle.com/#!2/c5d3d/5/0
As what i have understood from the query you gave you were selecting unique id's from the votes table and I assume that your column id is not an identity. but it would be better if that would be an identity? and if so, here is my answer.replace your select with these.
Select count (votes.participant.id) as count_id ,participants.name as participant_name
from participants join votes
on participants.id = vote.participant_id
group by participants.name
order by count_id
just let me know if it works
cheers
I have three tables that I need get information from, 1 table has the information in and the other two hold information that i need to count.
so the first tables structure is:
tbl_img
img_id
img_name
tbl_comments
comment_id
img_id
comment
tbl_vote
vote_id
logo_id
I want the results to have the count of comments and votes that relate to each logo.
I have a bit of the query which is for the count of comments, but have no idea for the syntax for the second join.
SELECT l.img_id, l.img_name, COUNT(c.comment_id) AS comment_count
FROM tbl_images as l
LEFT OUTER JOIN tbl_comments AS c USING (img_id);
Can anyone help?
how about this :
SELECT l.img_id, l.img_name,
(SELECT COUNT(*) FROM tbl_comments c WHERE i.img_id = c.img_id ) AS comment_count,
(SELECT COUNT(*) FROM tbl_vote v WHERE i.img_id = v.img_id ) AS vote_count
FROM tbl_images i
Sounds like you need two queries for this: One for counting the votes, and one for counting the comments.
As far as I know, COUNT counts result rows, and joins create result rows to display all allowed permutations of joined tables.
Assuming you have I entries, each with J comments and K votes, you would receive J*K rows for each entry after joins, and COUNTs would both return that J*K instead of the correct amount.
I do not remember if you can do inner queries in MySQL, but that would be the way to go.
(See #Kevin Burtons answer)