I have a blog, and I want to make a sql query, to provide all the blogs that belong to several arbitrary categories.
I thought I could do it with
SELECT * FROM `blog` WHERE `blog_category_id` IN($categories) ORDER BY RAND() LIMIT 10
But then I forgot that the categories come from another table, and now I am really struggling to work this out.
So I am trying to return all the info from the rows in the blog table, and find the blogs from the blogs_to_cats table
blogs_to_cats table contains blog_id and blog_category_id.
So what I have is an array of blog_category_id's, from here I want to generate the query.
What is the correct sql query to accomplish something like this, some sort of array table join?
SELECT blog.*
FROM blog b
INNER JOIN blog_to_cat bc ON b.id = bc.blog_id
WHERE bc.blog_category_id IN $categories
Related
$query = mysqli_query($conn, "SELECT BLOGGER_URL, COUNT(*) as NUM FROM Blog_Posts GROUP BY URL ORDER BY NUM DESC");
I'm using this query to return rows of data ordered based on the number of posts that a blogger has made. Each post has a blogger url ascribed to it, so I'm counting the number of blogger urls to determine the count.
I'm trying to order some rows based on the the number of posts made by a a blogger but right now the query only returns values that have a count of 1 or more. So Bloggers with no posts are not returned.
How can I edit the query to return ALL the bloggers in order?
Thanks, I'm pretty new to databases in general.
EDIT:
I have two tables relevant here: a bloggers table with a primary key blogger url and a blog posts table that uses the blogger url as a FK. The blog posts refer to a given blogger in the bloggers table
You should join your query to the users table so that you get a count of all users not just those with posts. I don't know your table structure, but you can do it in the following basic way.
SELECT Blog_Users.userid, COUNT(Blog_Posts.*) as NUM
FROM Blog_Users
LEFT OUTER JOIN Blog_Posts ON Blog_Posts.BLOGGER_USERID= Blog_Users.userid
GROUP BY Blog_Users.userid ORDER BY NUM DESC
It's normal that you have a count of 1 or more, cause the Bloggers that have not post does not exist in Blog_Post table, so if you want them returned, just join your Bloggers Table in the query with a left join.
Hope this heleped you
I hope itll be legal to post this as i'm aware of other similar posts on this topic. But im not able to get the other solutions to work, so trying to post my own scenario. Pretty much on the other examples like this one, im unsure how they use the tablenames and rows. is it through the punctuation?
SELECT bloggers.*, COUNT(post_id) AS post_count
FROM bloggers LEFT JOIN blogger_posts
ON bloggers.blogger_id = blogger_posts.blogger_id
GROUP BY bloggers.blogger_id
ORDER BY post_count
I have a table with articles, and a statistics table that gets new records every time an article is read. I am trying to make a query that sorts my article table by counting the number of records for that article id in the statistics table. like a "sort by views" functions.
my 2 tables:
article
id
statistics
pid <- same as article id
Looking at other examples im lacking the left join. just cant wrap my head around how to work that. my query at the moment looks like this:
$query = "SELECT *, COUNT(pid) AS views FROM statistics GROUP BY pid ORDER BY views DESC";
Any help is greatly appreciated!
SELECT article.*, COUNT(statistics.pid) AS views
FROM article LEFT JOIN statistics ON article.id = statistics.pid
GROUP BY article.id
ORDER BY views DESC
Ideas:
Combine both tables using a join
If an article has no statistics, fill up with NULL, i.e. use a left join
COUNT only counts non-NULL values, so count by right table to give correct zero results
GROUP BY to obtain exactly one result row for every article, i.e. to count statistics for each article individually
I have a database of Facebook Likes from several people. There are duplicate "like_id" fields across many "user_id"s. I want a query that will find the amount of "like_id"s person A has in common with person B.
This query is fantastic for comparing likes when only 2 "user_id"s are in the database, but as soon as I add a 3rd, it messes it up. Basically, I want to see who has the most "likes" in common with with person A.
SELECT *,
COUNT(*)
FROM likes
GROUP BY like_id
HAVING COUNT(*) > 1
Anyone have a query that might work?
This SQL should work. You just need to put in the User A's user_id and it should compare with all other users and show the top matching one. You can change it to show the top 5 or do whatever else you need to do.
Basically what it is doing is that it is doing a self join on the table, but making sure that when it does a join, it is a different user_id but the "like" is the same. Then it does a group by each of the other user_id's and sums the same amount of likes for that user_id.
SELECT all_other_likes.user_id, count(all_other_likes.like_id) AS num_similar_likes
FROM likes original_user_likes
JOIN likes all_other_likes
ON all_other_likes.user_id != original_user_likes.user_id
AND original_user_likes.like_id = all_other_likes.like_id
WHERE original_user_likes = USER_ID_YOU_WANT_TO_COMPARE
GROUP BY all_other_likes.user_id
ORDER BY count(all_other_likes.like_id) DESC
LIMIT 1;
Not sure what database you are using. You might need to do a SELECT TOP 1 if it is MS-SQL, but this is valid PostgreSQL and MySQL syntax.
I think this will do it:
SELECT
likes_a.user_id,
likes_b.user_id
FROM
likes as likes_a JOIN likes as likes_b
ON
likes_a.like_id = likes_b.like_id
WHERE
likes_a.user_id <> likes_b.user_id
And then post-process the results to count up who has the most in common.
I have a (what I am hoping to be easy) problem with a MySQL query.
I have 2 tables: articles, comments
An article can have many comments so there is a foreign of article_id in the comments table.
I want to get all the articles and while loop them to show on the page and then get all the comments count for each article. Easy, this is done. Now the problem is I want to sort the results based on number of comments but still show the results in the same way.
So basically I want to:
SELECT *
FROM tbl_articles
JOIN tbl_comments
ORDER BY (the most comments);
I am hoping this can all be done in a single query as the entire query is build dynamically from multiple sets of checkboxes where a single query could look like:
SELECT *
FROM tbl_articles
WHERE subject IN (1,2,5)
AND medium IN (1,3)
AND date_active > NOW()
AND...
Any further information I am happy to provide.
Something like...
SELECT *, COUNT(tbl_comments.id) as comments_count
FROM tbl_articles JOIN tbl_comments ON (tbl_comments.article_id = tbl_articles.id)
GROUP BY tbl_comments.article_id
ORDER BY comments_count;
MySQL setup: step by step.
programs -> linked to --> speakers (by program_id)
At this point, it's easy for me to query all the data:
SELECT *
FROM programs
JOIN speakers on programs.program_id = speakers.program_id
Nice and easy.
The trick for me is this. My speakers table is also linked to a third table, "books." So in the "speakers" table, I have "book_id" and in the "books" table, the book_id is linked to a name.
I've tried this (including a WHERE you'll notice):
SELECT *
FROM programs
JOIN speakers on programs.program_id = speakers.program_id
JOIN books on speakers.book_id = books.book_id
WHERE programs.category_id = 1
LIMIT 5
No results.
My questions:
What am I doing wrong?
What's the most efficient way to make this query?
Basically, I want to get back all the programs data and the books data, but instead of the book_id, I need it to come back as the book name (from the 3rd table).
Thanks in advance for your help.
UPDATE:
(rather than opening a brand new question)
The left join worked for me. However, I have a new problem. Multiple books can be assigned to a single speaker.
Using the left join, returns two rows!! What do I need to add to return only a single row, but separate the two books.
is there any chance that the books table doesn't have any matching columns for speakers.book_id?
Try using a left join which will still return the program/speaker combinations, even if there are no matches in books.
SELECT *
FROM programs
JOIN speakers on programs.program_id = speakers.program_id
LEFT JOIN books on speakers.book_id = books.book_id
WHERE programs.category_id = 1
LIMIT 5
Btw, could you post the table schemas for all tables involved, and exactly what output (or reasonable representation) you'd expect to get?
Edit: Response to op author comment
you can use group by and group_concat to put all the books on one row.
e.g.
SELECT speakers.speaker_id,
speakers.speaker_name,
programs.program_id,
programs.program_name,
group_concat(books.book_name)
FROM programs
JOIN speakers on programs.program_id = speakers.program_id
LEFT JOIN books on speakers.book_id = books.book_id
WHERE programs.category_id = 1
GROUP BY speakers.id
LIMIT 5
Note: since I don't know the exact column names, these may be off
That's typically efficient. There is some kind of assumption you are making that isn't true. Do your speakers have books assigned? If they don't that last JOIN should be a LEFT JOIN.
This kind of query is typically pretty efficient, since you almost certainly have primary keys as indexes. The main issue would be whether your indexes are covering (which is more likely to occur if you don't use SELECT *, but instead select only the columns you need).