Top Comment Sql query - php

There is a problem with my MySql query. Could you help me out with it?
I have a database as in the picture above, and there are userids that belongs to each user. It should be sorted by type descending. It records the time with the PHP time() function which is written at that moment in the datetime cell within the database. However, the SQL query which I used gives me a result as in the picture below:
SELECT
user.username,
kim.userid,
kim.subject,
count(kim.userid),
max(kim.dateline),
max(kim.rateid)
FROM test as kim
INNER JOIN user
WHERE user.userid = kim.userid
GROUP BY kim.userid limit 10)
Although I get the right results, I’m still having a little problem since the rateid does not show the right subject. So, I’ve been searching for it for two days, and I think there’s a problem that I don't understand or cannot see.
The right query should be like the on in the following picture:
I appreciate if you help!

You are trying to get information from the line that has the maximum rateid, along with aggregated information. For this, you need to join back to the original table:
select kim.userid, u.username, kim.cnt, kim.maxdate, kim.maxrate, t.subject
from (SELECT kim.userid, count(kim.userid) as cnt,
max(kim.dateline) as maxdate, max(kim.rateid) as maxrate
FROM test kim
GROUP BY kim.userid
limit 10
) kim INNER JOIN
user u
on u.userid = kim.userid join
test t
on kim.userid = t.userid and
kim.maxrate = t.rateid
This finds the maxrate for each user and then joins back to the table to get the subject for that rate. Your maxdate column seems to be what you want. If you want the date for the maxrate then you might also want to take it from t.

try this
Select user.username, kim.userid ,kim.subject, count(kim.userid), max(kim.dateline),
max(kim.rateid)
from test as kim
left join user ON user.userid = kim.userid group by kim.userid limit 10

Thanks for attention ,
i found the solution of my problem. The solution should be like this:
SELECT subject FROM test WHERE
userid=user.userid ORDER BY dateline desc LIMIT 1)
AS subject,
(SELECT COUNT(*) FROM test
WHERE userid=user.userid) AS adet
FROM user limit 10

Related

Left join and count in same query return incorrect result

The problem is that if there is 0 comment or 1 comment the count shows 1 while the rest is working well means that 2, 3, etc working fine.
$sql = "SELECT blog.*,count(blog.id) as Total FROM blog left JOIN comment on comment.id = blog.id GROUP BY date desc";
Your query should look like this:
SELECT b.date, count(c.id) as Total
FROM blog b LEFT JOIN
comment c
ON c.id = b.id
GROUP BY b.date DESC;
This assumes that date comes from blog (which should be the case if your current query is working). The difference is that you are counting from the second table, not the first.
This does not use * for columns from blog. That is usually a very, very bad idea when using GROUP BY. The best practice (enforced by almost all SQL engines) is to only include unaggregated columns in the SELECT when they are in the GROUP BY.
Note: It seems very awkward that the same column id is used for the JOIN between two very different entities (blogs and comments).
i just change to count(comment.id) from count(blog.id)

Need to check which row has most likes between two tables

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.

SQL Joins across multiple tables

I am building an online survey system for which I wish to produce statistics. I want query based on the gender of the user. I have the following tables:
survey_question_options
survey_answer
users
I have constructed the following query so that it brings back a null response where there are no answers to the question:
SELECT COUNT(sa.option_id) AS answer , so.option_label
FROM survey_answer sa
RIGHT JOIN survey_question_options so
ON sa.option_id = so.option_id AND
sa.record_date>='2011-09-01' AND
sa.record_date<='2012-08-01'
LEFT JOIN users u
ON (sa.uid = u.uid AND u.gender='F')
WHERE so.question_id=24
GROUP BY so.option_label
ORDER BY so.option_id ASC
My query returns the following results set:
0 Red
1 Yellow
0 Blue
0 Green
However, the gender condition in the LEFT JOIN appears to be ignored in the query. When I change the gender to 'M' the same result is returned. However, the expected result would be 0 for everything.
I am not sure where I am going wrong. Please help.
Thanks in advance.
Well, you are doing a COUNT on a column from the main table, so the gender condition on the LEFT JOIN won't affect the result. You should do the COUNT on a column from the users table. I'm not sure if this is what you want, but you should try:
SELECT COUNT(u.uid) AS answer , so.option_label
FROM survey_answer sa
RIGHT JOIN survey_question_options so
ON sa.option_id = so.option_id AND
sa.record_date>='2011-09-01' AND
sa.record_date<='2012-08-01'
LEFT JOIN users u
ON (sa.uid = u.uid AND u.gender='M')
WHERE so.question_id=24
GROUP BY so.option_label
ORDER BY so.option_id ASC
The left join to the users table is evaluated after the join to the answer table - so although the user record is not returned if the user is the wrong gender, the answer record will be returned (regardless of the user's gender). Try:
SELECT COUNT(sa.option_id) AS answer , so.option_label
FROM (select a.option_id
from survey_answer a
JOIN users u ON a.uid = u.uid AND u.gender='F'
where a.record_date>='2011-09-01' AND
a.record_date<='2012-08-01') sa
RIGHT JOIN survey_question_options so
ON sa.option_id = so.option_id
WHERE so.question_id=24
GROUP BY so.option_label
ORDER BY so.option_id ASC
You're putting your condition in the wrong block. Since you're performing a LEFT JOIN, (which is a left-bound outer join) everything in the left table (the main table) is selected, together with the data from the joined table, where applicable. What you want is to add the data from all users and then restrict the full output of the query. What you've actually done is add the user data from only the female users and then displayed all data.
Sounds technical, but all you have to do is move the AND u.gender='F' into the main WHERE clause instead the ON clause. That will cause SQL to only select the rows for female users after the JOIN has taken place.

inner join large table with small table , how to speed up

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

Retrieving like counts on entries from SQL

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.

Categories