im looking for a way in php to grab entries from a table named 'answers' in a mysql database, then grab entries from a table called 'votes' and calculate from them, the answer with the highest vote. I cant seem to find any help on this.
The structures can be viewed here
How it works is the users vote gets stored in the 'votes' table and is recognized by the 'answer_id' column, i just dont no how count them all and determine the answer with the highest votes
what about
SELECT a.*, COUNT(v.id) tot
FROM answers a INNER JOIN votes v
on a.id = v.answer_id
GROUP BY a.id
ORDER BY tot DESC
If you want to get also answers without any vote, use:
SELECT a.*, COUNT(v.id) tot
FROM answers a LEFT JOIN votes v
on a.id = v.answer_id
GROUP BY a.id
ORDER BY tot DESC
Related
I am trying to find a way to properly write a query to get the student answers for each question. I am not very good with SQL so I appreciate any help. This is for a student report I am building in PHP/MySQL
Firstly I have a question_table which stores the questions.
structure is:
id
question
Then I have a student table which has the student details.
structure is
id
student_name
Then I have an answers table, which contains each question_id and student_id.
structure is:
id
question_id
student_id
answer
I want to create a report where for each listed question. It shows the answer for each student. Something like:
Question: What is the name of the largest planet in the Solar System
Student A: Jupiter
Student B: Jupiter
Student C: Saturn
I have tried below but it does not work correctly...:
select * from question, student
inner join answer
where answer.question_id = question.id
Another challenge is that the report should be paginated. So first 20 questions per page. If a question has multiple student answers then the count will be more and I am not sure how I can paginate this correctly :(
You seem to want two joins. This gives you one row per question/student:
select q.question, s.student_name, a.answer
from answers a
inner join questions q on q.id = a.question_id
inner join students s on s.id = a.student_id
order by q.id, s.id
You can implement the pagination logic with window functions (available in MySQL 8.0):
select *
from (
select q.question, s.student_name, a.answer,
dense_rank() over(order by q.id) rn
from answers a
inner join questions q on q.id = a.question_id
inner join students s on s.id = a.student_id
) t
where rn between ? and ?
order by q.id, s.id
The two question marks represent the range of questions you want. The first question has index 1, and so on.
For pagination logic you have to use LIMIT keyword.It's supported to your server version.
Query like :
SELECT q.question, s.student_name, a.answer
FROM answers a
INNER JOIN questions q ON q.id = a.question_id
INNER JOIN students s ON s.id = a.student_id
ORDER BY q.id, s.id LIMIT 0,20
Now, you will get record 0 to 20.
Using of this you have to specify there are more data for get if yes then call next page and your LIMIT 20,20(have to make your own calculation For get offset according to pagination)
If there are no data for next page then stop execute query.
I've two tables in MySQL: tracks and ratings. I want the query to count how much ratings there are per track, that's why I use the following:
SELECT t.*, COUNT(*) as ratings
FROM tracks t, ratings r
WHERE t.trackID = r.trackID
GROUP BY t.trackID
ORDER BY ratings DESC
Well my problem now is, that when a track doesn't have a rating yet (so count is 0) it won't show, but I also want it to show when there aren't any ratings yet. I hope someone can help me. Thanks in advance! Steven.
Try this, hope you'll find it helpful.
SELECT t.*, (select count(*) from ratings r where r.trackID = t.trackID) as ratingsCount from tracks t order by ratingsCount DESC;
You must use LEFT JOIN to preserve all left side (i.e. tracks) records.
SELECT t.*, COUNT(*) as ratings
FROM tracks t
LEFT JOIN ratings r
ON t.trackID = r.trackID
GROUP BY t.trackID
ORDER BY ratings DESC
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.
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.
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