I'm fairly new to MYSQL!
I need to make a SQL query where i check how many likes a row has (between two tables)
I found another question that looked like mine, but i can't get it to return anything (even though it doesn't create an error.
query:
SELECT *
FROM likes
INNER JOIN (SELECT likes.like_id,
COUNT(*) AS likes
FROM likes
INNER JOIN uploads ON likes.upload_id=uploads.upload_id
WHERE uploads.upload_date >= DATE_SUB(CURDATE(), INTERVAL 8 DAY)
GROUP BY uploads.upload_id) x ON x.like_id = likes.like_id
ORDER BY x.likes DESC
Link to the original question:
MySQL, Need to select rows that has the most frequent values in another table
Help is much appreciated
Kind regards,
Mathias
Since you didn't post your table structure I'll have to guess..
select someid, count(*) cnt from
(
select * from table1 t1 join table2 t2 on t1.someid = t2.someid
) as q0 group by someid order by cnt desc;
It will need tweaking to fit your schema.
Related
I'm kind of noobie to this, but I'm trying to learn, I have two tables, the first one (NEWS) has all the information about posts of a blog, it has the follow structure:
* NEWS (TABLE 1)
- id_new
- id_category
- date
- ...etc
- **likes**
and I have a second table:
* LIKES (TABLE 2)
- id_like
- id_new
- id_user
- date
- ip_user
So, I want to select all the rows from TABLE 1 to display all the news but also i want to count the likes and get the COUNT of each new as like column.
This approach left joins the NEWS table to a subquery which finds the number of likes for each news story.
SELECT
t1.*,
COALESCE(t2.likes, 0) AS likes
FROM NEWS t1
LEFT JOIN
(
SELECT id_new, COUNT(*) AS likes
FROM LIKES
GROUP BY id_new
) t2
ON t1.id_new = t2.id_new
Note that here a story having no likes would not appear at all in the LIKES table and would receive a count of zero. Also note that I assume that every record in the LIKES table corresponds to a logical like. If not, then the query could be modified to count something else.
You can do it like this
SELECT table1.*, table2.*, count(table2.id_like) as like FROM news AS table1
INNER JOIN likes AS table 2 ON table1.id_new = table2.id_new;
OR
SELECT table1.*, table2.*, count(table2.id_like) as like FROM news AS table1
LEFT JOIN likes AS table 2 ON table1.id_new = table2.id_new;
you can use prepared statement
for example
$stmt = $pdo->prepare("SELECT count(*) FROM TABLE_1);
$stmt2 = $pdo->prepare("SELECT count(*) FROM TABLE_2);
//then execute
just read more on prepared statement
Try this
SELECT n, (SELECT count(*) FROM like l WHERE l.id_new = n.id_new) FROM news n
Use something like :
SELECT *, (SELECT COUNT(*) FROM LIKES WHERE LIKES.id_new =id_new) AS newsLikesCount FROM NEWS ORDER BY date;
This query would return all news and their number of likes
select n1.* , numberOfLikes.number_of_likes
from news n1
left join
(select n.id_news, count(l.id_like) as number_of_likes
from news n
left join likes l on n.id_news = l.id_new
group by n.id_news) numberOfLikes on n1.id_news = numberOfLikes.id_news
The important concepts here is understanding how two tables are joined together (1), how group by works(2), and how to aggregate l.id_likes using count(3).
(1). Left join preserves everything in the NEWS table and join them
with news link to the news.
(2). Then we group the rows base on id_news from the news. However,
mysql gets confused because it doesn't know what to do with id_like
from the likes table that we included in our select clause. Don't
worry my friend, This is where count comes in.
(3). We count the number of id_likes base for each id_news since we
are grouping the rows base on id_news.
I hope this helps. and welcome to StackOverfow. If you find this answer of any other answer helpful please mark it as the solution. That way it will help the community and fellow programmers in the future if they run into the same problem as you. Cheers.
Edit: to include all columns from news table we simply join the result from above back to the news table itself. and we select everything from the news table n1 and only number_of_likes from the result we created above.
I have found a problem I can't solve by myself.
I have users in table AE_Users where I store their special Points
Additionaly I have AE_Event table where I store events the users can join to, and for these events I am storing play time in seconds (timestamp) which is taken care of by CRON script checking players on server.
There is another table named AE_EventJoin where user is stored when he joins one of the events (so there can be multiple records of one user joining multiple event IDs)
I am able to calculate one user's point count by using 3 SQLs in PHP script:
SELECT `SteamID` FROM AE_Users WHERE `SteamID` = $SteamID
SELECT SUM(`EventInfo`) FROM AE_Events WHERE ID IN (SELECT `EventID` FROM AE_EventJoin WHERE `JoinType` = 1 AND `SteamID` = '$SteamID')
SELECT `Points` FROM AE_Users WHERE `SteamID` = $SteamID
but now I need to get top 5 users with most points and I really couldn't solve how to query the DB to give them to me.
I don't want to query DB for all users and then sort them in PHP, that would be too ugly.
I believe there is a way on how to calculate the user points from single SQL query. I tried to build it myself, but it is not working as expected. I was able to come up with this:
SELECT T1.`SteamID`, T1.`Points` AS PointCount, SUM(T2.`EventInfo`) AS PointCount FROM AE_Users T1, AE_Events T2 WHERE T2.ID IN (SELECT `EventID` FROM AE_EventJoin WHERE `JoinType` = 1 AND `SteamID` = T1.`SteamID`) ORDER BY PointCount LIMIT 5
which returns this: phpMyAdmin result
and that is wrong. It return only one user and the first PointCount is user's special point count which is correct, but the second PointCount is totally wrong viz. picture
phpMyAdmin Event points
And I would like to merge those two variables into one PointCount but GROUP BY command didn't allow me to do it because of some error. It is not a big issue though, I can merge them in PHP easily.
So is there any way on how to get the information I need from tables with structure like I have?
You are missing a group by clause , so try this:
SELECT T1.`SteamID`, max(T1.`Points`) AS PointCount, SUM(T2.`EventInfo`) AS PointCount
FROM AE_Users T1
INNER JOIN AE_Events T2
ON T2.ID IN (SELECT `EventID` FROM AE_EventJoin
WHERE `JoinType` = 1
AND `SteamID` = T1.`SteamID`)
GROUP BY T1.`SteamID`
ORDER BY PointCount
LIMIT 5
Also, you used implicit(comma separated) join syntax, please try to avoid this and use the correct syntax of explicit joins like in my solution.
You didn't post your table structures so it was hard to guess what exactly do you need, but it is something similar to this.
This query can also be written with a join instead of IN()
SELECT T1.`SteamID`, max(T1.`Points`) AS PointCount, SUM(T2.`EventInfo`) AS PointCount
FROM AE_Users T1
INNER JOIN `EventID` T3
ON(t1.`steamID` = t3.`steamID` and `JoinType` = 1 AND `SteamID` = T1.`SteamID`)
INNER JOIN AE_Events T2
ON (T2.ID = T3.ID)
GROUP BY T1.`SteamID`
ORDER BY PointCount
LIMIT 5
dear php and mysql expertor
i have two table one large for posts artices 200,000records (index colume: sid) , and one small table (index colume topicid ) for topics has 20 record .. have same topicid
curent im using : ( it took round 0.4s)
+do get last 50 record from table:
SELECT sid, aid, title, time, topic, informant, ihome, alanguage, counter, type, images, chainid FROM veryzoo_stories ORDER BY sid DESC LIMIT 0,50
+then do while loop in each records for find the maching name of topic in each post:
while ( .. ) {
SELECT topicname FROM veryzoo_topics WHERE topicid='$topic'"
....
}
+Now
I going to use Inner Join for speed up process but as my test it took much longer from 1.5s up to 3.5s
SELECT a.sid, a.aid, a.title, a.time, a.topic, a.informant, a.ihome, a.alanguage, a.counter, a.type, a.images, a.chainid, t.topicname FROM veryzoo_stories a INNER JOIN veryzoo_topics t ON a.topic = t.topicid ORDER BY sid DESC LIMIT 0,50
It look like the inner join do all joining 200k records from two table fist then limit result at 50 .. that took long time..
Please help to point me right way doing this..
eg take last 50 records from table one.. then join it to table 2 .. ect
Do not use inner join unless the two tables share the same primary key, or you'll get duplicate values (and of course a slower query).
Please try this :
SELECT *
FROM (
SELECT a.sid, a.aid, a.title, a.time, a.topic, a.informant, a.ihome, a.alanguage, a.counter, a.type, a.images, a.chainid
FROM veryzoo_stories a
ORDER BY sid DESC
LIMIT 0 , 50
)b
INNER JOIN veryzoo_topics t ON b.topic = t.topicid
I made a small test and it seems to be faster. It uses a subquery (nested query) to first select the 50 records and then join.
Also make sure that veryzoo_stories.sid, veryzoo_stories.topic and veryzoo_topics.topicid are indexes (and that the relation exists if you use InnoDB). It should improve the performance.
Now it leaves the problem of the ORDER BY LIMIT. It is heavy because it orders the 200,000 records before selecting. I guess it's necessary. The indexes are very important when using ORDER BY.
Here is an article on the problem : ORDER BY … LIMIT Performance Optimization
I'm just give test to nested query + inner join and suprised that performace increase much: it now took only 0.22s . Here is my query:
SELECT a.*, t.topicname
FROM (SELECT sid, aid, title, TIME, topic, informant, ihome, alanguage, counter, TYPE, images, chainid
FROM veryzoo_stories
ORDER BY sid DESC
LIMIT 0, 50) a
INNER JOIN veryzoo_topics t ON a.topic = t.topicid
if no more solution come up , i may use this one .. thanks for anyone look at this post
I'm kind of new to SQL and I can't find the solution to my problem. I have two tables. In table A, I'm storing a lot of comments, each with a unique ID.
In table B, I'm storing every vote (like=1 and dislike=0) for every comment with a datetime. There will be an entry for every vote, so there will be tons of rows for each comment in table A.
I need to retrieve all the comments and sort them such that the weekly most liked comments are at the top, but I'm not sure how.
Here's what I have so far, but not sure how to continue:
SELECT * FROM comment INNER JOIN logs ON comment.c_id=logs.c_id WHERE logs.daterate >= DATE_SUB(CURDATE(), INTERVAL 8 DAY) AND logs.rated=1
To clarify, I need to get all entries from logs with rated = 1 in the past week and sort them by the most frequent c_id in descending order, and get distinct c_id for each row... if that makes sense
Please ask questions if I didn't make it clear enough, thanks!!
SELECT *
FROM comment
INNER JOIN (SELECT comment.c_id,
COUNT(*) AS cnt
FROM comment
INNER JOIN logs ON comment.c_id=logs.c_id
WHERE logs.daterate >= DATE_SUB(CURDATE(), INTERVAL 8 DAY)
AND logs.rated=1
GROUP BY comment.c_id) x ON x.c_id = comment.c_id
ORDER BY x.cnt DESC
Try this -
I have first queried all records from logs table which are rated 1 and are from 7 days from current date and also are ordered based on the count of c_id. Then joined this with the COmments table.
SELECT Comment.* FROM comment C
INNER JOIN (SELECT logs.c_id as c_id,count(logs.c_id) as logcount FROM logs
WHERE logs.rated=1
AND logs.daterate BETWEEN GETDATE() AND DATEADD(day,-7,getdate())
Group by logs.c_id
order by count(logs.c_id) desc) X
ON C.c_id = X.c_id
ORDER BY X.logcount DESC
I've been adding a like feature to an entries database... here's the structure of the DBs:
**Users**
user_id
user_name
etc.
**Entries**
entry_id
entry_content
etc.
**Likes**
user_id
entry_id
(It's a little more complicated than that, there are groups/categories, but that should explain it fine...) Here's the SQL query I'm working with at the moment:
SELECT
entries.*,
DATE_FORMAT(entry_date, "%M %D, %Y") as entry_date,
groups.group_short_name,
users.user_name, users.user_id,
FROM entries
INNER JOIN groups ON groups.group_id = entries.group_id
INNER JOIN users ON users.user_id = entries.user_id
ORDER BY entry_date DESC
I'm trying to also retrieve likes per entry with this query and wondering if it is possible. I've been trying:
COUNT(DISTINCT likes.like_id) as likes
with
LEFT JOIN likes ON likes.entry_id = entries.entry_id
But I don't think that is anywhere near right. Am I way off? Is this possible? Hope it all made sense.
Thanks for the help in advance.
Give your tables aliases, for one..
FROM entries e
Then add a column query:
select e.*, (select count(*) from Likes where entry_id = e.entry_id) as entry_likes
Add:
GROUP BY entries.entry_id
See if that works.