Hello I want to display the name of the activities according to the order of their addition in the feed (FeedId=incremented id) and with a preselected team number however the order in the subquery is not respected.
MariaDB [database]
select name from activity where id=(select ActivityId from feed where TeamId=16 order by FeedId);
I tried to take out the order by but without success. Someone would have any idea ?
Try using inner join, something like this
select name
from activity
inner join feed on feed.ActivityId = activity.id
where TeamId=16
order by FeedId;
Related
Suppose I have two tables, users and posts. Posts has the following fields, userid, postid, etc and userid can appear multiple times as one user can write multiple posts....I'm just trying sort the users table based off the # of occurrences per userid in the posts table. I can get the # of occurrences per user using this
SELECT userid, COUNT(*)
FROM posts
GROUP BY userid;
I would like to use the values under COUNT(*) column, maybe add it to my other table because then I can simply to something like this
SELECT * FROM users
ORDER BY newcolumn ASC;
but I'm having trouble doing that. Or can I do it without having to add an extra column? Hints please. Thanks
Left join is the key here!
SELECT users.userid,count(posts.userid) AS total_count
FROM users
LEFT JOIN posts on posts.userid = users.userid
GROUP BY users.userid
ORDER BY total_count DESC;
We are taking the left join on two tables with same user_id and we are counting the total number of posts per user using group by. Finally sort by count and show results.
try an left join:
select users.userid, [user fields],count(postid) as posts_count
from users
left join posts on posts.userid = users.userid
group by users.userid,[user fields]
order by posts_count desc.
You want to select users (FROM users) but you want to sort based on criteria in another table (COUNT(*) FROM posts) -- therefore you need to use a JOIN
Off-hand I can't seem to recall if "JOIN" or "RIGHT JOIN" or "FULL JOIN" is what you need if you wanted to get a cartesian product of the tables then group and aggregate on a single field, but I can avoid the need to remember with a subquery (hopefully someone will soon post a smaller and smarter answer):
SELECT users.* FROM users
JOIN (
SELECT userid, COUNT(*) as count
FROM posts
GROUP BY userid
) as subquery ON users.id = subquery.userid
ORDER BY subquery.count
Note: I haven't tested this query, but it looks good to me. Again: hopefully someone will post a better answer soon as I'm not doing my due dilligence, but you definitely need a JOIN :)
You could add a post_count column to the users table, but you would also have to update that count column every time a user creates a new post and you would have to build that logic into your application.
Otherwise, it looks like the answer from FallAndLearn will get you what you need.
I'm working on a project and I have a problem. I have a table namedfriendswith three columnid,from_emailandto_email(it's a social networking site and "from_email" is the person that follows the "to_email"). I want a query to return the top 5 friends I follow according to the number of their followers. I know that the query for top 5 is:
SELECT
to_mail,
COUNT(*) AS friendsnumber
FROM
friends
GROUP BY
to_email
ORDER BY
friendsnumber DESC
LIMIT 5
Any ideas?
I would also like to return friends with the same number of followers ordered by their name. Is it possible?
You should use COUNT(from_email) instead of COUNT(*); because you want to calculate the number of followers, which is represented by from_email.
Thus, your select clause would be something like:
SELECT to_email, COUNT(from_email) as magnitude
as for getting the most popular people that you follow, you could use IN clause:
WHERE to_email IN (SELECT to_email FROM friends WHERE from_email='MY_EMAIL');
and about name, you shall join this query with the other table which contains the name value.
Since you've got the essentials now, I hope you can try to compose the full query on your own =)
Join again to the table for the 2nd tier count:
SELECT f1.to_email
FROM friends f1
JOIN friends f2 on f2.to_mail = f1.to_email
WHERE f1.from_email = 'myemail'
GROUP BY 1
ORDER BY count(*) DESC
LIMIT 5
If an index is defined on to_email, this will perform very well.
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 a query that joins a couple of tables and produces a lot of rows, in a situation where I only wish to see one row per user. I have solved the "only one user" problem by using group by user.id, however, I'm noticing that now for each user I get the values from the joined table that represent the first entry (rather than the last).
so in other words
user:
id | phone
item:
id | user_id | timestamp
my intention is to join these tables and select the latest item (based on timestamp, or item.id desc) but to only get one item per user (rather than see all the items that each user has). group by user.id solves the problem of giving me just one item per user, but they always turn up with the first item that has the lowest item.id, whereas I want the most recent one.
Is there a better way to achieve this... I was initially noodling with distinct but that doesn't seem to do the trick.
TIA
[EDIT]
In response to Jocelin's question below:
select user.id, item.timestamp from item join user on user.id = item.user_id order by user.id
mysql has a "cheat" for getting the first row only of each group:
select *
from (select
u.id as user_id,
u.name,
i.id as item_id,
i.timestamp
from user u
join item i on i.user_id = u.id
order by timestamp desc -- "desc" = order descending
) x
group by user_id
The "cheat" is that mysql allows you not aggregate the non-group by columns (unlike every other database I know). Instead of giving an SQL syntax error, it returns the first record only of each group. Not SQL standard, but very handy.
The beauty of this is that you don't need any correlated subqueries, which are dreadfully slow.
The inner query is used to order the records in timestamp latest-first order, so the first record encountered for each user is the "most recent".
Use an ORDER BY with DESC clause:
select
user.id, item.timestamp
from
item
join
user on user.id = item.user_id
group by
user.id
order by
user.id DESC
I'm suspecting (from your comments below) that your issue isn't really what you describe. Try something like this instead (untested, because I don't use MySQL - it works in SQL Server and SQLite):
select
user.id, i.ts
from
(select id, max(timestamp) as ts from items group by id) i
join
user u on u.id = i.id
You will need to use a JOIN. First create a subselect grouping by user and selecting the MAX of timestamp. This gets you one row per user, with the latest entry (and loses all other fields).
Then join it back using the timestamp in the JOIN expression, to restore the missing fields.
Sorry, but without the table schema it isn't easy to be more specific than this. Hope that the JOIN reference points you in the right direction to modify your query.
Any kind soul that can help me retreive latest published image in a bucket (collection) to show instead of the first posted? The code below works, that would love the show the latest added image instead of the first added in the database.
Here is the MySQL query I'm using:
SELECT t.*, bt.*, d.*
FROM collection_images bt, collections t, images d
WHERE bt.collection_id = t.unique_id
AND (t.creator IN ($dropper_id))
AND d.unique_id = bt.image_id
GROUP BY bt.collection_id
Here are the tables:
collections
id
name
unique_id
creator
*collection_images*
id
collection_id
unique_id
image_id
images
id
image_url
unique_id
title
date
Thank you!
I have rewritten the query -
SELECT c.*, images.*
FROM collections c
INNER JOIN (
SELECT collection_id, MAX(images.id) AS max_id
FROM collection_images
INNER JOIN images
ON collection_images.image_id = images.unique_id
GROUP BY collection_id
) AS latest
ON c.unique_id = latest.collection_id
INNER JOIN images
ON latest.max_id = images.id
WHERE (c.creator IN ($dropper_id))
UPDATE now using images.id instead of images.date as the second join to collection_images is then not needed.
you can try order images.id desc also i am not sure your date field what it store ?
if timestamp then you can use this.