How to fetch users by rating with mysql query? (Top Rated) - sql

There is a query I've just made
SELECT *
FROM users
INNER JOIN ratings ON ratings.rateable=users.id
ORDER BY SUM(ratings.rating)/COUNT(ratings.rating)
But, it doesn't work, I just get one person in result, although there are 3 people in ratings table! I'm using php 5.
I think sum(), count() doesn't work at all!
Please, help!! Cause I can't understand how to build TOP RATED system.

This is just a hunch, but ratings.rateable smells like a bit to me. Any chance the one result has users.id 1?
Is ratings.rateable really the foreign key to users.id?

It's hard to tell because I can't see all of your stuff....but my guess is in the ' ON ratings.rateable=users.id ' part of your SQL. Are you storing the users.id field value in the rateable column in your ratings table?

Related

SQL Query - select multiple rows from 2 tables

I'm new to SQL and recently saw this question, which is described on the [attached picture]
. Any suggestions on how to solve it? Thanks in advance.
In most cases such requirements are better to resolve by starting from the end. Let's try that: "have more than 3 items ... and total price".
select InvoiceId, sum(price)
from InvoiceItem
group by InvoiceId
having count(1) > 3;
This query gives you the overall price for every invoice that has more than 3 items. You might be wondering why there is that funny "having" clause and not the "where" clause.
The database executes first "from" and "where" parts of the query to get the data and only after that using aggregations (sum, count etc.) is possible, so they are to be specified afterwards.
The query above actually returns all the data from requirement, but I assume that whoever gave you this task (that was a teacher, right?) was asking you to retrieve all the data from Invoices table that correspond to the records within the InvoiceItem table that has more than 3 items and so on.
So, for now all you have left is to join the Invoice table with a query from above
select i.id, i.customername, i.issuedate, sum(it.price)
from InvoiceItem it
join Invoice i on it.invoiceid = i.id
group by i.id, i.customername, i.issuedate
having count(1) > 3;
Teacher might ask you why did you use count(1) and not count(*) or count(id) or something. Just tell him/her all these things are equal so you picked just one.
Now it should be working fine presumably. I did not tested it at all as you did not provide the data to test it on and it is late so I am pretty tired. Because of this you might needed to fix some typos or syntax errors I probably made - but hey let's keep in mind you still have to do something on your own with this task.

Find the number of certifications held by people, grouped by planet.

This is part of my SQL homework and I can't wrap my head around it. It should have two colums, name and CertCount. Where name = planet name. and CertCount = total number of certificates all people with that homeworld have.
These are the tables i'm working with: http://pastebin.com/kNRNGQFv
This is my query so far:
SELECT bsg_people.homeworld, (SUM(cid)
AS 'CertCount'
FROM bsg_people
INNER JOIN bsg_cert_people ON id=cid)
GROUP BY bsg_people.homeworld;
I just can't seem to figure this out because there is no value to count the number of certificates each person has. I appreciate any help.
Use a simple count(*), without the subquery and join to the right column - your pastebin shows that the foreign key to person is on pid (not cid):
CONSTRAINT `bsg_cert_people_ibfk_2` FOREIGN KEY (`pid`) REFERENCES `bsg_people` (`id`)
Also, join to the planets tables to get the name of the planet in your output.
Try this:
select bsg_planets.name homeworld, count(*) CertCount
from bsg_planets
join bsg_people on bsg_planets.id = bsg_people.homeworld
join bsg_cert_people on id = pid
group by bsg_planets.name
Also, you had a syntax error: You quoted the alias "CertCount" like this: 'CertCount', but that's a string literal. You need an alias, without quotes, like this CertCount.
Rather than answer your question directly (which would sort of defeat the purpose of the homework which is for you to learn), I'll try to point you in the right direction :)
How are you joining bsg_cert_people onto bsg_people? Look at which fields are referring to people and which are referring to certifications, and make sure that you're using them the correct way. While not essential in this case, using table aliases (instead of just "id=cid") and neatening up the query a bit can really help with getting a better mental picture of what the joins and such are doing.

Getting highest value in many to many relation

I use Oracle DB .I have for example 3 tables:
User (id_user,username)
Interest (id_interest,name)
UserInterest(id_user_interest,id_user,id_interest)
I'd like to get all users, together with name of interest, which has the highest id_user_interest in UserInterest table. What is the best way to get it in sql query?
Thanks for the help
This should work to get the user with the highest user interest hopefully...
I do not have access to a compiler so this is all a guess.
SELECT TOP 1 U.username, I.name FROM user U
JOIN user_interest UI ON U.id_user=UI.id_user
JOIN interest I ON UI.id_interest=I.id_interest
GROUP BY U.username
ORDER BY UI.id_user_interest ASC
The TOP attribute grabs the first x amount of results and the ORDER BY blank ASC attribute orders the results from highest to lowest.
Hopefully this works for you, and GL programming. :)

How do you JOIN tables to a view using a Vertica DB?

Good morning/afternoon! I was hoping someone could help me out with something that probably should be very simple.
Admittedly, I’m not the strongest SQL query designer. That said, I’ve spent a couple hours beating my head against my keyboard trying to get a seemingly simple three way join working.
NOTE: I'm querying a Vertica DB.
Here is my query:
SELECT A.CaseOriginalProductNumber, A.CaseCreatedDate, A.CaseNumber, B.BU2_Key as BusinessUnit, C.product_number_desc as ModelNumber
FROM pps_sfdc.v_Case A
INNER JOIN reference_data.DIM_PRODUCT_LINE_HIERARCHY B
ON B.PL_Key = A.CaseOriginalProductLine
INNER JOIN reference_data.DIM_PRODUCT C
ON C.product_line_code = A.CaseOriginalProductLine
WHERE B.BU2_Key = 'XWT'
LIMIT 20
I have a view (v_Case) that I’m trying to join to two other tables so I can lookup a value from each of them. The above query returns identical data on everything EXCEPT the last column (see below). It's like it's iterating through the last column to pull out the unique entries, sort of like a "GROUP BY" clause. What SHOULD be happening is that I get unique rows with specific "BusinessUnit" and "ModelNumber" for that record.
DUMEPRINT 5/2/2014 8:56:27 AM 3002845327 JJT Product 1
DUMEPRINT 5/2/2014 8:56:27 AM 3002845327 JJT Product 2
DUMEPRINT 5/2/2014 8:56:27 AM 3002845327 JJT Product 3
DUMEPRINT 5/2/2014 8:56:27 AM 3002845327 JJT Product 4
I modeled my solution after this post:
How to deal with multiple lookup tables for beginners of SQL?
What am I doing wrong?
Thank you for any help you can provide.
Data issue. General rule in trouble shooting these is the column that is distinct (in this case C.product_number_desc as ModelNumber) for each record is generally where the issue is going to be...and why I pointed you towards dim_product.
If you receive duplicates, this query below will help identify if this table is giving you the issues. Remember key in this statement can be multiple fields...whatever you are joining the table on:
Select key,count(1) from table group by key having count(1)>1
Other options for the future...don't assume it's your code, duplicates like this almost always point towards dirty data (other option is you are causing cross joins because keys are not correct). If you comment out the 'c' table and the column referred to in the select clause, you would have received one row...hence your dupes were coming from the 'c' table here.
Good luck with it

How to combine data from 2 tables under circumstances?

I have 2 tables. One table contains posts and the other contains votes for the posts. Each member can vote (+ or -) for each post.
(Structure example:)
Posts table: pid, belongs, userp, text.
Votes table: vid, userv, postid, vote.
Also one table which contains the info for the users.
What I want is: Supposing I am a logged-in member. I want to show all the posts, and at those I've already voted, not let me vote again. (and show me what I have voted + or -)
What I have done til now is very bad as it will do a lot of queries:
SELECT `posts`.*, `users`.`username`
FROM `posts`,`users`
WHERE `posts`.belongs=$taken_from_url AND `users`.`usernumber`=`posts`.`userp`
ORDER BY `posts`.`pid` DESC;
and then:
foreach ($query as $result) {if (logged_in) {select vote from votes....etc} }
So, this means that if I am logged in and it shows 30 posts, then it will do 30 queries to check if at each post I have voted and what I've voted. My question is, can I do it shorter with a JOIN (I guess) and how? (I already tried something, but didn't succeed)
Firstly I'll say that if you're going to have significantly different output for users logged in versus those that aren't, just have two queries rather than trying to create something really complicated.
Secondly, this should do something like what you want:
SELECT p.*, u.username,
(SELECT SUM(vote) FROM votes WHERE postid = p.pid) total_votes,
(SELECT vote FROM votes WHERE postid = p.pid AND userv = $logged_in_user_id) my_vote
FROM posts p
JOIN users u ON p.userp = u.usernumber
WHERE p.belongs = $taken_from_url
ORDER BY p.pid DESC
Note: You don't say what the values of the votes table are. I'm assuming it's either +1 (up) or -1 (down) so you can easily find the total votes by adding them up. If you're not doing it this way I suggest you do to make your life easier.
The first correlated subquery can be eliminated by doing a JOIN and GROUP BY but I tend to find the above form much more readable.
So what this does is it joins users to posts, much like you were doing except that it uses JOIN syntax (which again comes down to readability). Then it has two subqueries: the first finds the total votes for that particular post and the second finds out what a particular user's vote was:
+1: up vote;
-1: down vote;
NULL: no vote.